Mac OS X 10.11.6 (El Capitan)의 알림 센터에 알림을 보내려고합니다. 이제는 Objective-C 전문가가 아니므로 this 샘플을 기본으로 사용하고 있습니다.Objective-C 및 CoreFoundation : i386에서 "인식 할 수없는 선택기 전송"오류가 발생했습니다.
전체 목록 : 64 비트 바이너리를 컴파일 할 때
//
// main.m
// badonkas
//
// Created by Yoshiki Vázquez Baeza on 21/07/13.
// Copyright (c) 2013 Yoshiki Vázquez Baeza. All rights reserved.
//
// Based on the source code as written by Norio Nomura for the project
// usernotification https://github.com/norio-nomura/usernotification
// gcc -framework Foundation main.m
//
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
NSString *fakeBundleIdentifier = nil;
@implementation NSBundle(swizle)
// Overriding bundleIdentifier works, but overriding NSUserNotificationAlertStyle does not work.
- (NSString *)__bundleIdentifier{
if (self == [NSBundle mainBundle]) {
return fakeBundleIdentifier ? fakeBundleIdentifier : @"com.apple.terminal";
} else {
return [self __bundleIdentifier];
}
}
@end
BOOL installNSBundleHook()
{
Class class = objc_getClass("NSBundle");
if (class) {
method_exchangeImplementations(class_getInstanceMethod(class, @selector(bundleIdentifier)),
class_getInstanceMethod(class, @selector(__bundleIdentifier)));
return YES;
}
return NO;
}
#pragma mark - NotificationCenterDelegate
@interface NotificationCenterDelegate : NSObject<NSUserNotificationCenterDelegate>
@property (nonatomic, assign) BOOL keepRunning;
@end
@implementation NotificationCenterDelegate
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification
{
self.keepRunning = NO;
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *message = [defaults stringForKey:@"-message"] ?: @"";
NSString *title = [defaults stringForKey:@"-title"] ?: @"Notification";
NSString *subtitle = [defaults stringForKey:@"-subtitle"] ?: @"";
if (installNSBundleHook()) {
fakeBundleIdentifier = [defaults stringForKey:@"identifier"];
NSUserNotificationCenter *nc = [NSUserNotificationCenter defaultUserNotificationCenter];
NotificationCenterDelegate *ncDelegate = [[NotificationCenterDelegate alloc]init];
ncDelegate.keepRunning = YES;
nc.delegate = ncDelegate;
NSUserNotification *note = [[NSUserNotification alloc] init];
note.title = title;
note.subtitle = subtitle;
note.informativeText = message;
[nc deliverNotification:note];
while (ncDelegate.keepRunning) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
}
return 0;
}
지금이 잘 작동합니다. 나는 -m32
또는 -arch i386
플래그와 32 비트 바이너리로 컴파일한다면, 그것은 충돌 :
2017-05-15 22:16:50.886 a.out[68034:2781117] -[NotificationCenterDelegate setKeepRunning:]: unrecognized selector sent to instance 0x7a019ef0
2017-05-15 22:16:50.886 a.out[68034:2781117] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NotificationCenterDelegate setKeepRunning:]: unrecognized selector sent to instance 0x7a019ef0'
*** Call stack at first throw:
(
0 CoreFoundation 0x9bc9d9b9 __raiseError + 201
1 libobjc.A.dylib 0x9e277fd1 objc_exception_throw + 276
2 CoreFoundation 0x9bca1463 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x9bb91dec ___forwarding___ + 1020
4 CoreFoundation 0x9bb919ce _CF_forwarding_prep_0 + 14
5 a.out 0x000608d5 main + 533
6 libdyld.dylib 0x90c4c6ad start + 1
)
68034: trace trap
왜이며, 해결 방법이?
(의심 할 여지없이 누군가가 [정당한 이유를 묻습니다] : 폐쇄 소스 32 비트 프로그램과 연결하려면 32 비트가 필요합니다. 그리고 64 비트 버전을 얻을 수 없습니다. 프로그램. 이미 32 비트 dylib를 연결하고이 문제를 다뤄 보았습니다.)
덕분에 명확한 설명 및 솔루션에 대한 무리. "Objective-C 전문가가 아닙니다"는 "나는 Objective-C를 전혀 모른다"라는 완곡 어법이었습니다. 이 경우 경고가 도움이되지 않습니다. –