Pass method as an SEL argument to another class method

1

I have an appDelegate that init an instance of a class called LocationService. I just want to pass to this instance by init a method that this class will run.

I got this exception:

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'

this is my app delegate class method that init the LocationService instance:

-(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;
}

And this is the LocationService class method:

-(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;
}

Please help me guys.
Thanks a lot!

objective-c
ios
ios-4.2
asked on Stack Overflow Aug 16, 2011 by Elad • edited Aug 16, 2011 by sidyll

3 Answers

2

A selector is just a method's name. It's not related to a class, nor an instance of a class.

If you want to have a kind of callback, using selectors, you'll have to provide a target object as well as the selector.

Then, invoke the selector to the target object, using the performSelector method, inherited from NSObject.

For error checking, see the respondToSelector method.

answered on Stack Overflow Aug 16, 2011 by Macmade
1

Remove the colon next to backgroundLocationUpdate as in below:

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

As the colon makes it to look for a method with (id)sender parameter.

answered on Stack Overflow Aug 16, 2011 by Saran
1

The error is coming from this line:

self.backgroundActionMethod = selector;

I'm guessing you don't actually have a backgroundActionMethod property, because there is no -setBackgroundActionMethod: method.

answered on Stack Overflow Aug 16, 2011 by jtbandes

User contributions licensed under CC BY-SA 3.0