0

I am getting JSON data from a server. Since data returned may be used for different purposes, different processing methods are required.

Below is my expected function:

- (void)getFrom:(NSString *)server method:(SEL)processingMethod {
    NSURL *url = [NSURL URLWithString:server];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    [req setHTTPMethod:@"GET"];
    [req setValue:@"application/x-www-form-urlencoded charset=utf-8"
forHTTPHeaderField:@"Content-Type"];

    [NSURLConnection sendAsynchronousRequest:req
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                               if (error) {
                                   NSLog(@"error requesting: %@", error.localizedDescription);
                                   return;
                               }

                               NSLog(@"data: %@", [[NSString alloc] initWithData:data
                                                                        encoding:NSUTF8StringEncoding]); // print JSON

                               // How to call appropriate method (passed from parameter) here??
                               [self passJSON:data toMethod:processingMethod];

                           }];
}

- (void)passJSON:(NSData *)data toMethod:(SEL)method {

    if ([self respondsToSelector:method]) {  
        [self performSelector:@selector(method) // WARNING: Undeclared selector method
                   withObject:data];
    }
}

- (void)processData1:(NSData *)JSON {
    // process data1
}

- (void)processData2:(NSData *)JSON {
    // process data2
} 

What would I do to call my function - (void)getFrom:(NSString *)server method:(SEL)processingMethod having any processingMethod of my interest passed in, such as:

- (void)somefunction {
    [self getFrom:@"http://www.datasite.com/data1" method:@selector(processData1:)]; // after getting data1, processData1 is called having JSON data1 passed in
    [self getFrom:@"http://www.datasite.com/data2" method:@selector(processData2:)]; // after getting data2, processData2 is called having JSON data2 passed in
}

Then I found this link (especially wbyoung's reply): performselector may cause a leak

But I could not figure out how to pass a parameter, in this case: JSON data, to someMethod

Any suggestion?

Thanks,

Community
  • 1
  • 1
quanguyen
  • 1,056
  • 1
  • 12
  • 25

1 Answers1

0

Thank to Scott's reply in the link above perform selector may cause a leak

I put some pragma marks around [self performSelector:method withObject:data] to silent the warning, and all work well.

Below is my complete code:

- (void)getFrom:(NSString *)server method:(SEL)processingMethod {
    NSURL *url = [NSURL URLWithString:server];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    [req setHTTPMethod:@"GET"];
    [req setValue:@"application/x-www-form-urlencoded charset=utf-8"
forHTTPHeaderField:@"Content-Type"];

    [NSURLConnection sendAsynchronousRequest:req
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                               if (error) {
                                   NSLog(@"error requesting: %@", error.localizedDescription);
                                   return;
                               }

                               NSLog(@"data: %@", [[NSString alloc] initWithData:data
                                                                        encoding:NSUTF8StringEncoding]); // print JSON

                               // How to call appropriate method (passed from parameter) here??
                               [self passJSON:data toMethod:processingMethod];

                           }];
}

- (void)passJSON:(NSData *)data toMethod:(SEL)method {

    if ([self respondsToSelector:method]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        [self performSelector:method
                   withObject:data];
#pragma clang diagnostic pop
    }
}

- (void)processData1:(NSData *)JSON {
    // process data1
}

- (void)processData2:(NSData *)JSON {
    // process data2
} 

Usage:

- (void)somefunction {
    [self getFrom:@"http://www.datasite.com/data1" method:@selector(processData1:)]; // after getting data1, processData1 is called having JSON data1 passed in
    [self getFrom:@"http://www.datasite.com/data2" method:@selector(processData2:)]; // after getting data2, processData2 is called having JSON data2 passed in
}

However, this approach is just to suppress the warning, not actually/completely solve the problem by coding in a right way. Any more suggestions, ideas are welcome!

Regards,

Community
  • 1
  • 1
quanguyen
  • 1,056
  • 1
  • 12
  • 25