Передать метод в качестве аргумента SEL другому методу класса - PullRequest
1 голос
/ 16 августа 2011

У меня есть appDelegate, который инициирует экземпляр класса с именем LocationService. Я просто хочу передать этому экземпляру init метод, который будет запускать этот класс.

Я получил это исключение:

2011-08-16 20:38:15.233 WalklogAnywhere[8258:307] -[LocationService setBackgroundActionMethod:]: unrecognized selector sent to instance 0x17a740
2011-08-16 20:38:15.249 WalklogAnywhere[8258:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[LocationService setBackgroundActionMethod:]: unrecognized selector sent to instance 0x17a740'
*** Call stack at first throw:
(
        0   CoreFoundation        0x314d0987 __exceptionPreprocess + 114
        1   libobjc.A.dylib       0x319a149d objc_exception_throw + 24
        2   CoreFoundation        0x314d2133 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102
        3   CoreFoundation        0x31479aa9 ___forwarding___ + 508
        4   CoreFoundation        0x31479860 _CF_forwarding_prep_0 + 48
        5   WalklogAnywhere       0x00004013 -[LocationService initWithBackgroundMethod:] + 206
        6   WalklogAnywhere       0x0000246b -[WalklogAnywhereAppDelegate application:didFinishLaunchingWithOptions:] + 110
        7   UIKit                 0x338dabc5 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 772
        8   UIKit                 0x338d6259 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 272
        9   UIKit                 0x338a248b -[UIApplication handleEvent:withNewEvent:] + 1114
        10  UIKit                 0x338a1ec9 -[UIApplication sendEvent:] + 44
        11  UIKit                 0x338a1907 _UIApplicationHandleEvent + 5090
        12  GraphicsServices      0x35d66f03 PurpleEventCallback + 666
        13  CoreFoundation        0x314656ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
        14  CoreFoundation        0x314656c3 __CFRunLoopDoSource1 + 166
        15  CoreFoundation        0x31457f7d __CFRunLoopRun + 520
        16  CoreFoundation        0x31457c87 CFRunLoopRunSpecific + 230
        17  CoreFoundation        0x31457b8f CFRunLoopRunInMode + 58
        18  UIKit                 0x338d5309 -[UIApplication _run] + 380
        19  UIKit                 0x338d2e93 UIApplicationMain + 670
        20  WalklogAnywhere       0x000021bb main + 70
        21  WalklogAnywhere       0x00002170 start + 40
)
terminate called after throwing an instance of 'NSException'

это мой метод класса делегата приложения, который инициирует экземпляр LocationService:

-(void) backgroundLocationUpdate {
    NSLog(@"location is updated in background");
}


#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application
     didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.

    [self.window makeKeyAndVisible];
    locationService = [[LocationService alloc]
            initWithBackgroundMethod:@selector(backgroundLocationUpdate:)];
    [locationService startForegroundService];
    storageService = [[StorageService alloc] init];
    [self loadApplicationData];

    return YES;
}

И это метод класса LocationService:

-(id) initWithBackgroundMethod:(SEL)selector {
    self = [super init];
    if (self != nil) {
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
        locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        self.backgroundActionMethod = selector;
    }
    return self;
}

Пожалуйста, помогите мне, ребята.
Большое спасибо!

Ответы [ 3 ]

2 голосов
/ 16 августа 2011

Селектор - это просто имя метода. Это не относится ни к классу, ни к экземпляру класса.

Если вы хотите иметь своего рода обратный вызов, используя селекторы, вам нужно будет предоставить целевой объект, а также селектор.

Затем вызовите селектор для целевого объекта, используя метод performSelector, унаследованный от NSObject.

Для проверки ошибок см. Метод respondToSelector.

1 голос
/ 16 августа 2011

Ошибка исходит из этой строки:

self.backgroundActionMethod = selector;

Я предполагаю, что у вас на самом деле нет свойства backgroundActionMethod, потому что нет метода -setBackgroundActionMethod:.

1 голос
/ 16 августа 2011

Удалить двоеточие рядом с backgroundLocationUpdate, как показано ниже:

[self.window makeKeyAndVisible]; locationService = [[LocationService alloc] initWithBackgroundMethod:@selector(backgroundLocationUpdate)]; 

Поскольку двоеточие заставляет его искать метод с параметром (id) отправителя.

...