objective-cmemory-managementnsinvocationoperation

NSInvocationOperation with bad access crash


I got a big problem with NSInvocationOperation. When I run on my iPod 4, firmware 5.0.1, it's OK. But on my iPhone 4, iOS 4.1, it crashed. This is my code:

CustomAnnotation *annotation = [[[ModelManager defaultModelManager] getAnnotationDictionaryInMemory] objectForKey:joltId];

if (annotation == nil)
   annotation = [[[ModelManager defaultModelManager] getAnnotationDictionaryInMemory] annotationWithInstagramId:eID];

if (annotation == nil)
    continue;
 //THIS ONE CRASH ON IPHONE 4 OS 4.1
NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys: @"aKey", @"aValue", nil];

NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:annotation selector:@selector(updateAnnotation:) object:param];

[_queue addOperation:op];
[op autorelease];

updateAnnotation function was defined in CustomAnnotation class:

- (void)updateAnnotation:(id)sender {
//NSLog(@"UPDATE ANNOTATION ID: %@", self.annoID);
NSDictionary *senderDic = (NSDictionary *)sender;
UzooltAppDelegate* appDelegate = (UzooltAppDelegate*) [UIApplication sharedApplication].delegate;

if ([senderDic objectForKey:@"nb_rejolt"] != nil) {
    NSInteger new_nb_rejolts = [[senderDic objectForKey:@"nb_rejolt"] intValue];
    //if (new_nb_rejolts != rejolts) {
        //NSLog(@"update nb rejolts: %d", new_nb_rejolts);

        if (self.rejolts != new_nb_rejolts) {
            self.rejolts = new_nb_rejolts;
            //if (self.isGrouped)
            //    [self.masterAnnotation.annotationView performSelectorOnMainThread:@selector(updateAnnotationViewWithRejolts:) withObject:[NSString stringWithFormat:@"%d", rejolts] waitUntilDone:NO];
            //else

            if ([senderDic objectForKey:@"rejolt_fbid"] != nil) {
                NSString *fbRejoltsString = [senderDic objectForKey:@"rejolt_fbid"];
                self.fbRejolts = [[fbRejoltsString componentsSeparatedByString:@","] mutableCopy];
                [self.fbRejolts removeLastObject];
                [self updateNumberOfRejoltsFromFBFrds];
            }

            [self.annotationView performSelectorOnMainThread:@selector(updateAnnotationViewWithRejolts:) withObject:[NSString stringWithFormat:@"%d", rejolts] waitUntilDone:NO];
        }

        if (self.isGrouped) {
            if (self.masterAnnotation.isShowingRadius == NO && appDelegate.uMainViewController.isInGroup == NO && ( new_nb_rejolts > self.masterAnnotation.rejolts || (new_nb_rejolts == self.masterAnnotation.rejolts && self.getAge < self.masterAnnotation.getAge))) {
                [self.masterAnnotation removeFromGroupedAnnotations:self];
                self.annotationView.hidden = NO;
                [self.annotationView performSelectorOnMainThread:@selector(showWithAlpha:) withObject:[NSNumber numberWithFloat:annotationAlpha] waitUntilDone:NO];
                [[NSNotificationCenter defaultCenter] postNotificationName:@"need_group_annotations" object:nil];
            }
        }
    //}
}

if ([senderDic objectForKey:@"lifetime"] != nil) {
    float new_lifetime = [[senderDic objectForKey:@"lifetime"] floatValue]*3600;
    //NSLog(@"new lifetime: %.f", new_lifetime);
    if (new_lifetime != lifetime) {
        //NSLog(@"update lifetime");
        self.lifetime = new_lifetime;
    }
}

[self updateViewAlpha];

if ([senderDic objectForKey:@"radius"] != nil) {
    float new_radius = [[senderDic objectForKey:@"radius"] floatValue];
    if (new_radius != radius) {
        //NSLog(@"update lifetime");
        self.radius = new_radius;
    }
}

/*
if ([appDelegate.uMainViewController isMaximumZoomIn])
    [[self annotationView] performSelectorOnMainThread:@selector(setGroupNumberIndicatorVisible:) withObject:[NSNumber numberWithBool:YES] waitUntilDone:NO];
else
    [[self annotationView] performSelectorOnMainThread:@selector(setGroupNumberIndicatorVisible:) withObject:[NSNumber numberWithBool:NO] waitUntilDone:NO];
*/

if (isSelected == YES && isShowingRadius == NO ) {
    //NSLog(@"update details");
    [self performSelectorOnMainThread:@selector(updateDetailsView) withObject:nil waitUntilDone:NO];

    UzooltAppDelegate* appDelegate = (UzooltAppDelegate*) [UIApplication sharedApplication].delegate;
    if (isGrouped == YES && appDelegate.uMainViewController.isInGroup) {
        NSLog(@"grouped jolt rejolted");
        [self performSelectorOnMainThread:@selector(updateInGroupAnnotationView) withObject:nil waitUntilDone:NO];
    }
}

}

I don't know where it wrong? Please help me. Thanks all !!!


Solution

  • Try running with NSZombies enabled. It should at least give you a hint as to what object you are trying to access after it has been deallocated.

    NSZombies enabled, debug information