开发者

Problems Adding to NSMutableArray: attempt to insert nil object at 10

Hey guys, so I am getting these inconsistent errors when running my program, only about 50% of the time do these errors occur, and at seemingly different points of my program. Here is the console output:

2011-05-11 14:22:03.926 Parking[20611:1903] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSMutableArray insertObject:atIndex:]: attempt to insert nil object at 10'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x011afbe9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x013045c2 objc_exception_throw + 47
    2   CoreFoundation                      0x011a97f1 -[__NSArrayM insertObject:atIndex:] + 225
    3   CoreFoundation                      0x011a4c44 -[__NSArrayM addObject:] + 68
    4   Parking                             0x000182fd -[DataLoader loadOverlaysFromStore] + 1521
    5   Parking                             0x00017b76 -[DataLoader main] + 64
    6   Foundation                          0x00c5ebd2 -[__NSOperationInternal start] + 747
    7   Foundation                          0x00c5e826 ____startOperations_block_invoke_2 + 106
    8   libSystem.B.dylib                   0x9488c024 _dispatch_call_block_and_release + 16
    9   libSystem.B.dylib                   0x9487e2f2 _dispatch_worker_thread2 + 228
    10  libSystem.B.dylib                   0x9487dd81 _pthread_wqthread + 390
    11  libSystem.B.dylib                   0x9487dbc6 start_wqthread + 30
)
terminate called after throwing an instance of 'NSException'

And:

2011-05-11 14:16:45.171 Parking[20500:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSMutableArray insertObject:atIndex:]: attempt to insert nil object at 2'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x011afbe9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x013045c2 objc_exception_throw + 47
    2   CoreFoundation                      0x011a97f1 -[__NSArrayM insertObject:atIndex:] + 225
    3   CoreFoundation                      0x011a4c44 -[__NSArrayM addObject:] + 68
    4   Parking                             0x00012887 -[CoreDataSingleton getParkingLotTitlesForPermits:] + 1030
    5   Parking                             0x00004891 -[ParkingMapViewController sortLotsIntoSetsAccordingToPermitsAccepted] + 616
    6   Parking                             0x00006317 -[ParkingMapViewController viewDidLoad] + 1474
    7   UIKit                               0x000fc65e -[UIViewController view] + 179
    8   UIKit                               0x000faa57 -[UIViewController contentScrollView] + 42
    9   UIKit                               0x0010b201 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 48
    10  UIKit                               0x00109831 -[UINavigationController _layoutViewController:] + 43
    11  UIKit                               0x0010ab4c -[UINavigationController _startTransition:fromViewController:toViewController:] + 524
    12  UIKit                               0x00105606 -[UINavigationController _startDeferredTransitionIfNeeded] + 266
    13  UIKit                               0x0021de01 -[UILayoutContainerView layoutSubviews] + 226
    14  QuartzCore                          0x01a15451 -[CALayer layoutSublayers] + 181
    15  QuartzCore                          0x01a1517c CALayerLayoutIfNeeded + 220
    16  QuartzCore                          0x01a15088 -[CALayer layoutIfNeeded] + 111
    17  UIKit                               0x000fdb5f -[UIViewController window:willAnimateRotationToInterfaceOrientation:duration:] + 587
    18  UIKit                               0x000768e9 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 4347
    19  UIKit                               0x002f5948 -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 1053
    20  UIKit                               0x00100982 -[UIViewController presentModalViewController:withTransition:] + 3151
    21  Parking                             0x0000b104 -[SampleHomeScreen appButtonTapped:] + 124
    22  UIKit                               0x0004ea6e -[UIApplication sendAction:to:from:forEvent:] + 119
    23  UIKit                               0x000dd1b5 -[UIControl sendAction:to:forEvent:] + 67
    24  UIKit                               0x000df647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
    25  UIKit                               0x000de1f4 -[UIControl touchesEnded:withEvent:] + 458
    26  UIKit                               0x000730d1 -[UIWindow _sendTouchesForEvent:] + 567
    27  UIKit                               0x0005437a -[UIApplication sendEvent:] + 447
    28  UIKit                               0x00059732 _UIApplicationHandleEvent + 7576
    29  GraphicsServices                    0x01424a36 PurpleEventCallback + 1550
    30  CoreFoundation                      0x01191064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
    31  CoreFoundation                      0x010f16f7 __CFRunLoopDoSource1 + 215
    32  CoreFoundation                      0x010ee983 __CFRunLoopRun + 979
    33  CoreFoundation                      0x010ee240 CFRunLoopRunSpecific + 208
    34  CoreFoundation                      0x010ee161 CFRunLoopRunInMode + 97
    35  GraphicsServices                    0x01423268 GSEventRunModal + 217
    36  GraphicsServices                    0x0142332d GSEventRun + 115
    37  UIKit                               0x0005d42e UIApplicationMain + 1160
    38  Parking                             0x00002424 main + 102
    39  Parking                             0x000023b5 start + 53
)
terminate called after throwing an instance of 'NSException'

I have run through it with a debugger and have not been able to determine at which point of my program it fails at, however, I do have an inkling it may be within this new section of code I wrote (tossed in additional retains here and there to help this error-will deal with releasing later):

-(id)initWithFunction:(LoaderFunc)func withDelegate:(id)delegate setRestricted:(NSSet *)restricted 
                 setA:(NSSet *)A setC:(NSSet *)C setL:(NSSet *)L {
    if (self = [super init]) {
        self.addedOverlays = [[NSMutableArray alloc] init];
        self.addedAnnotations = [[NSMutableArray alloc] init];
        self.overlayRegions = [[NSMutableArray alloc] init];
        self.loaderFunc = func;
        self.DLDelegate = delegate;
        return self;
    }
    return nil;
}
//...
-(void)loadOverlaysFromStore {
    NSLog(@"DataLoader.m loadOverlaysFromStore");
    //NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSDictionary *permits;
    permits = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"0",@"0",@"0",nil] forKeys:[NSArray arrayWithObjects:@"A",@"C",@"L",nil]];
    NSSet *setOfRestrictedLots = [[NSSet setWithArray:[[CoreDataSingleton sharedManager] getParkingLotsForPermits:permits]] retain];
    NSMutableArray *arrayOfRestrictedLotTitles = [[NSMutableArray alloc] init];
    for (ParkingLot *l in [setOfRestrictedLots allObjects]) {
        [arrayOfRestrictedLotTitles addObject:[[l lotName]retain]];
    }
    permits = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1",@"0",@"0",nil] forKeys:[NSArray arrayWithObjects:@"A",@"C",@"L",nil]];
    NSSet *setOfALots = [[NSSet setWithArray:[[CoreDataSingleton sharedManager] getParkingLotsForPermits:permits]] retain];
    NSMutableArray *arrayOfALotTitles = [[NSMutableArray alloc] init];
    for (ParkingLot *l in [setOfALots allObjects]) {
        [arrayOfALotTitles addObject:[[l lotName]retain]];
    }
    permits = [NSDictionary dictionaryWithObjects:[NSArray arrayWith开发者_开发知识库Objects:@"1",@"1",@"0",nil] forKeys:[NSArray arrayWithObjects:@"A",@"C",@"L",nil]];
    NSSet *setOfCLots = [[NSSet setWithArray:[[CoreDataSingleton sharedManager] getParkingLotsForPermits:permits]] retain];
    NSMutableArray *arrayOfCLotTitles = [[NSMutableArray alloc] init];
    for (ParkingLot *l in [setOfCLots allObjects]) {
        [arrayOfCLotTitles addObject:[[l lotName]retain]];
    }
    permits = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1",@"1",@"1",nil] forKeys:[NSArray arrayWithObjects:@"A",@"C",@"L",nil]];
    NSSet *setOfLLots = [[NSSet setWithArray:[[CoreDataSingleton sharedManager] getParkingLotsForPermits:permits]] retain];
    NSMutableArray *arrayOfLLotTitles = [[NSMutableArray alloc] init];
    for (ParkingLot *l in [setOfLLots allObjects]) {
        [arrayOfLLotTitles addObject:[[l lotName]retain]];
    }

    [addedOverlays addObject:setOfRestrictedLots];
    [addedOverlays addObject:setOfALots];
    [addedOverlays addObject:setOfCLots];
    [addedOverlays addObject:setOfLLots];


    for (NSSet* set in addedOverlays) {
        for (ParkingLot *lot in [set allObjects]) {

            ParkingRegionOverlay *regionPolygon = [[ParkingRegionOverlay alloc] initWithPoints:[lot overlayCoordPoints]
                                                                                      andTitle:[lot lotName] 
                                                                                 setRestricted:[NSSet setWithArray:arrayOfRestrictedLotTitles]
                                                                                          setA:[NSSet setWithArray:arrayOfALotTitles] 
                                                                                          setC:[NSSet setWithArray:arrayOfCLotTitles] 
                                                                                          setL:[NSSet setWithArray:arrayOfLLotTitles]];
            [overlayRegions addObject:regionPolygon];
            [regionPolygon release];
        }
    }


}//loadOverlays

Any help greatly appreciated. Thanks!


So I figured it out. Remember how I said it occurred only about 50% of the time? That was a HUGE hint by the way as I had some code that retrieved data from my Core Data Store that was accessed in two ways. I had modified my code to have a background thread access that method but forgot to remove the call to it from a portion of the code where the main thread operates. Thus there would be race conditions in accessing the data, and I am not too sure why it would result in obtaining a nil value in some cases, but removing the call to that function from the main thread rectified the problem.


So the debug message is pretty self explanatory: at some point, you're trying to insert an object that doesn't exist into your array.

Since based on the logs you posted it seems to be happening in several places in your application the best strategy is to ensure it's impossible to insert a nil value into your arrays in the first place.

I would recommend you either a) establish what's causing these nil values to come up (presumably bad input data), and b) if you're unable to get your input data to behave correctly, defensively code your app to take that into account.

To be honest, it's probably a good idea to check you're not trying to insert a nil value object anyway. You could either use a try/catch statement to catch the exception when it happens, or test the object before you inserted it:

if ([l lotname]) {
    [arrayOfALotTitles addObject:[[l lotName]retain]];
}

(PS: not sure why you're explicitly retaining when you add to an array. Normally you wouldn't need to do this. Hope you're matching it back with a corresponding release call!).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜