我遇到了一个让我完全不知所措的问题。我会用代码示例来说明:
@interface Crasher ()
@property (nonatomic, strong) NSArray *array;
@end
@implementation Crasher
- (void)crash;
{
NSMutableArray *mutable = [NSMutableArray array];
NSArray *items = @[@0, @1, @2, @3];
if ([@YES boolValue])
{
[items enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[mutable addObject:obj];
}];
}
else
{
[items enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[mutable addObject:obj];
}];
}
[self setArray:mutable];
}
@end
当启用ARC并在设备上运行时,以上代码在
[self setArray:mutable]
行崩溃。该代码在模拟器上不会崩溃,禁用ARC的设备也不会崩溃。使用NSZombieEnabled
指示setter试图保留已释放的数组。如果注释掉第二个
[mutable addObject:obj]
调用,则不会崩溃(但是这段代码首先就没有执行)。我已经将演示此崩溃的项目上传到Github上
aidansteele/arc-crash
。 我正在使用Xcode 4.5.2。 它似乎不会发生在Xcode 4.6上,但那仍处于开发人员预览阶段。 我做错了什么?
针对this问题的解答(为了让我有更多的空间,放在问题中),我认为问题不在-[NSArray enumerateObjectsUsingBlock:]
方法内,因为如果我将该方法调用更改为使用以下-[NSArray(Functional) each:]
调用,问题仍然存在。
@interface NSArray (Functional)
- (void)each:(void (^)(id obj))action;
@end
@implementation NSArray (Functional)
- (void)each:(void (^)(id))action;
{
for (NSUInteger idx = 0; idx < [self count]; idx++)
{
action([self objectAtIndex:idx]);
}
}
@end
array
一起使用。 - Rad'ValNSMutableArray *mutable = [@[] mutableCopy];
或者其他传统增加保留计数的方法,效果同样良好。 - Rad'Val