1

Hey so I am getting the classic EXC_BAD_ACCESS (Code = 1, address = 0x10) and can't seem to figure out why. I get the error with the following method:

+ (void)logoutWithXId:(NSString *)xId compelationHandler:(void (^)(BOOL))hasSucceeded
{
    NSError *error;

    // create json object for a users session
    NSDictionary *session = [NSDictionary dictionaryWithObjectsAndKeys:
                             xId, @"x_id",
                             nil];

    NSData *jsonSession = [NSJSONSerialization dataWithJSONObject:session options:NSJSONWritingPrettyPrinted error:&error];

    NSString *url = [NSString stringWithFormat:@"%@xsession/logout", potCatURL];

    NSURL *URL = [NSURL URLWithString:url];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL
                                                           cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                       timeoutInterval:30.0];

    NSString *headerValue = [NSString stringWithFormat:@"Token token=%@", APIToken];

    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setValue:headerValue forHTTPHeaderField:@"Authorization"];
    [request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[jsonSession length]] forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody:jsonSession];

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

        if (error == nil)
        {
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
            NSInteger statusCode = httpResponse.statusCode;

            if (statusCode == 200)
            {
                //********************* error happens here *******************************
                hasSucceeded(true);
            }
            else
            {
                hasSucceeded(false);
            }
        }
        else
        {
            hasSucceeded(false);
        }
    }];
}

When I call the method like so:

[Xsession logoutWithXId:[userInfo stringForKey:@"x_id"] compelationHandler:nil]

I get the EXC_BAD_ACCESS error but when I call it like:

[Xsession logoutWithXId:[userInfo stringForKey:@"x_id"] compelationHandler:^(BOOL hasCreated){}]

with an empty compilationHandler it runs fine. Why is this happening, can someone please explain?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
ScottOBot
  • 839
  • 3
  • 16
  • 37

2 Answers2

7

It's due to the nil handler. You must always do the following:

if (hasSucceeded) {
    hasSucceeded(someValue);
}

The crash is caused by dereferencing the nil block pointer. This is different from trying to call a method on a nil variable reference (which is fine). You must never dereference a nil block pointer.

There is some great information about this in another answer here.

Community
  • 1
  • 1
rmaddy
  • 314,917
  • 42
  • 532
  • 579
2

The reason you get a crash is that you don't check whether passed argument is nil or not. Blocks in this case are different (you should treat it like a pointer to a function not like NSObject subclass). You cannot call a function on address 0.

To fix it you should check if the block is not nil before calling it:

if (hasSucceded) {
    hasSucceeded(value);
}
blazejmar
  • 1,080
  • 8
  • 10