【问题标题】:NSArray deep copy causes crashNSArray 深拷贝导致崩溃
【发布时间】:2011-10-07 17:38:47
【问题描述】:

我已经盯着这段代码看了一段时间,但不知道到底哪里出了问题。我有一个名为 SortFilteringController 的类,它管理我在系统中拥有的不同过滤(内部过滤器、公共过滤器、排序选项等)。这些中的每一个都存储在一个数组中。所以我有一个方便的方法,它基本上采用这些数组中的任何一个,并用一些新数据重置它们。

例如setInternalFilter,直接调用即可。

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

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

resetArray 的定义,就是将已有的数据转储(释放),并将新数据复制过来。

- (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];    

}

但我的问题是我在重置方法中遇到了崩溃。不在模拟器中,仅在设备上。

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 initWithArray: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)

我正在运行带有 iOS 5.0 GM 种子的 xcode 4.2。我的设备仍在运行 4.1.3。但这不应该有所作为吧?错误是“doesNotRecognizeSelector”。多么奇怪。

谢谢。

【问题讨论】:

  • 请输入错误的完整文本——我发现模拟器中存在接口但设备中没有接口的实例。它不识别哪个选择器?

标签: objective-c ios nsmutablearray nsarray deep-copy


【解决方案1】:

检查oldArray == newData。你会注意到在 Objective-C 中集合操作的默认习惯用法是这样的:

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

如果 newThing == 事物,并且您删除了当前事物,那么您很可能会导致它调用其析构函数。所以你总是先做保留。

因此,您可以释放要复制的对象。而且,使用最新最好的垃圾收集器,该设备的清理速度可能比模拟器快。两个平台上都存在错误,但内存管理器的不确定性可能会让您认为它是暂时的。

如果没有其他问题,请检查您的代码以确保您没有释放您可能需要稍后在函数中使用的对象。仅仅因为变量名称不同,并不意味着它们不是同一个对象。

【讨论】:

  • 这就是原因。在为我解决问题之前先保留。
【解决方案2】:

会不会是数组中存储的对象不符合NSCopying协议?所以当初始化器尝试在它们上调用copy 方法时,他们只是不知道如何处理它?

【讨论】:

    猜你喜欢
    • 2010-10-13
    • 2023-04-09
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 2015-01-13
    • 2011-09-05
    • 1970-01-01
    相关资源
    最近更新 更多