Objective-C: Pass selector as parameter and then call it
Solution 1
That is because you are trying using the target-action pattern but not passing a target. I would actually recommend the delegate approach but here is an example of what your interface should look like.
@interface HttpRequest : NSObject
{
@private
id onEndTarget; //<- need to know who to send the message to (do not retain)
SEL onEndSel;
NSMutableData* receivedData;
}
//Accept the target here
-(void) StartRequest:(NSString *) url
parameters:(NSString*) params
onEndTarget:(id)target
onEndSelector:(SEL) selector;
//... implementation
-(void) connectionDidFinishLoading:(NSURLConnection*) connection
{
[onEndTarget performSelector:onEndSel withObject:[[NSMutableData alloc] initWithData:receivedData]];
}
//...
//Inside App Delegate
[req StartRequest:url parameters:@"a" onEndTarget:self onEndSelector:@selector(OnFinishConn:)];
Make sure you do not retain the onEndTarget because that could create a retain cycle. Also consider making the target a property so if something is done with the connection before it complete it can stop being the delegate.
Solution 2
You're sending the selector to self
, but that's in HttpRequest. The selector you're trying to call is in AppDelegate. So you're sending the selector to an object that doesn't implement it. To fix, you should store not just the selector but a pointer to the object to which the selector should be sent.
Related videos on Youtube
Payn3
Updated on June 04, 2022Comments
-
Payn3 about 2 years
i'm trying to pass a selector as a parameter and execute it later. But i get a SIGABRT error when i try to call the selector with the next error in console:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[HttpRequest OnFinishConn:]: unrecognized selector sent to instance 0x7834c80'
HttpRequest.h
#import <Foundation/Foundation.h> @interface HttpRequest : NSObject { @private SEL onEndSel; @private NSMutableData* receivedData; } -(void) StartRequest:(NSString *) url parameters:(NSString*) params onEndSelector:(SEL) selector; @end
HttpRequest.m
#import "HttpRequest.h" @implementation HttpRequest -(void) StartRequest:(NSString *)url parameters:(NSString*)params onEndSelector:(SEL)selector { receivedData = [[NSMutableData alloc] init]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]]; onEndSel = selector; NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; } -(void) connectionDidFinishLoading:(NSURLConnection*) connection { //NSLog([[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding]); [self performSelector:onEndSel withObject:[[NSMutableData alloc] initWithData:receivedData]]; } -(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ [receivedData appendData:data]; } @end
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. //self.window.backgroundColor = [UIColor whiteColor]; HttpRequest* req = [[HttpRequest alloc] init]; SEL mysel = @selector(OnFinishConn:); NSString * url = [[NSString alloc] initWithString:@"http://www.google.es"]; [req StartRequest:url parameters:@"a" onEndSelector:@selector(OnFinishConn:)]; [self.window makeKeyAndVisible]; return YES; } -(void)OnFinishConn:(NSMutableData *)data { NSLog([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); }
I'm new in objective c, so please be patient.
-
Payn3 almost 13 yearsThanks all for your responses. It worked well with Joe's code.
-
Joe almost 13 yearsGlad they helped be sure to mark a question as answered once your problem is resolved and welcome to StackOverflow!.
-
Logicsaurus Rex about 7 yearsBrillliant. This should be the answer