开发者

NSArray deep copy causes crash

I've been staring at this code for a while now, but can't figure out what in the world is wrong. I have a class called SortFilteringController, which manages the different filtering that I have in the system (internal filter, public filter, sort options, etc). Each of these is stored in an array. So I have a convience method, which basically takes any of these arrays, and resets them with some new data.

For example, the setInternalFilter, just calls it.

- (void) setInternalFilterTerms : (NSArray*) filterTerms {

    [self resetArray: &_internalFilters withNewData:filterTerms];
}

The definition of resetArray, is just to dump the existing one (release it), and copy the new data across.

- (void) resetArray: (NSMutableArray**) oldArray withNewData : (NSArray*) newData {

    if (*oldArray != nil) {
        [*oldArray release];
    }


    NSMutableArray* newArray = [[NSMutableArray alloc] initWithArray:newData copyItems:YES];
    *oldArray = [newArray retain];
    [newArray release];    

}

But my problem is I get a crash in the reset method. Not in the simulator, only on the device.

Thread 0 Crashed:
0   libsystem_kernel.dylib          0x331a3a1c __pthread_kill + 8
1   libsystem_c.dylib               0x3404c3b4 pthread_kill + 52
2   libsystem_c.dylib               0x34044bf8 abort + 72
3   libstdc++.6.dylib               0x30e4fa64 __gnu_cxx::__verbose_terminate_handler() + 376
4   libobjc.A.dylib                 0x30fda06c _objc_terminate + 104
5   libstdc++.6.dylib               0x30e4de36 __cxxabiv1::__terminate(void (*)()) + 46
6   libstdc++.6.dylib               0x30e4de8a std::terminate() + 10
7   libstdc++.6.dylib               0x30e4df5a __cxa_throw + 78
8   libobjc.A.dylib                 0x30fd8c84 objc_exception_throw + 64
9   CoreFoundation                  0x33e5f1b8 -[NSObject(NSObject) doesNotRecognizeSelector:] + 96
10  CoreFoundation                  0x33e5e642 ___forwarding___ + 502
11  CoreFoundation                  0x33dd5178 _CF_forwarding_prep_0 + 40
12  CoreFoundation                  0x33dcb156 -[NSArray initWi开发者_如何学运维thArray:range:copyItems:] + 366
13  CoreFoundation                  0x33dcafce -[NSArray initWithArray:copyItems:] + 54
14  Wine DB 1.1                     0x001b6a2a -[SortFilterController resetArray:withNewData:] (SortFilterController.m:1310)
15  Wine DB 1.1                     0x001b4188 -[SortFilterController setInternalFilterTerms:] (SortFilterController.m:733)

I am running xcode 4.2 with iOS 5.0 GM seed. My device is still running 4.1.3. But that shouldn't make a difference right? And the error is "doesNotRecognizeSelector". How strange is that.

Thanks.


Check to see if oldArray == newData. You'll notice that the default idiom for a set operation in Objective-C is this:

-(void) setFoo:(NSThing *)newThing
{
    [newThing retain];
    [thing release];
    thing = newThing;
}

If newThing == thing, and you delete the current thing, then you may well cause it to call its destructor. So you always do the retain first.

So it's possible your releasing the very objects you want to copy. And, using the latest-and-greatest garbage collectors, the device may be cleaning up faster than the simulator. The bugs is there on both platforms, but the indeterminate nature of the memory manager can make you think it's transient.

If nothing else, review your code to make sure you're not releasing objects you might need to be using later in the function. Just because the variable names are different, it doesn't mean they aren't the same object.


Could it be that come of the objects stored in an array does not conform to NSCopying protocol? So when initializer tries to call copy method on them they just don't know how to handle it?

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜