私は完全に困惑する問題にぶつかりました。コードサンプルで説明します:
@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
上記のコード[self setArray:mutable]
は、ARC が有効になっており、デバイス上で実行されると、回線上でクラッシュします。コードがシミュレーターでクラッシュしたり、ARC が無効になっているデバイスでクラッシュしたりすることはありません。UsingNSZombieEnabled
は、セッターが既に割り当て解除された配列を保持しようとしていることを示します。
2 番目の呼び出しがコメント アウトされていてもクラッシュしません[mutable addObject:obj]
(ただし、このコードが最初に実行されることはありません)。
このクラッシュを示すプロジェクトを Github にアップロードしましたaidansteele/arc-crash
。Xcode 4.5.2 を使用しています。Xcode 4.6 では発生しないようですが、まだ開発者プレビュー段階です。私は何を間違っていますか?
この回答に対処して(質問でもう少しスペースを空けてください)、-[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