Обновление: Это было исправлено в iOS 6.1 DP3 SDK.
Я выследил сбой при использовании после ARC, используя конфигурацию сборки по умолчанию (отладка, похоже, работает нормально). Проблема возникает при создании объекта внутри if-scope с непостоянным условием, присваивая его переменной извне области, а затем ссылается только на переменную с помощью массива Objective-C или словарных литералов.
Вот самый маленький воспроизводимый случай, который мне удалось найти:
void test(BOOL arg)
{
id obj = nil;
if (arg) {
obj = [NSObject new];
}
// obj already deallocated here
@[obj];
// but using NSArray works
//[NSArray arrayWithObject:obj];
// @[obj] works if obj is referenced i.e. by NSLog print out
//NSLog(@"%@", obj);
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
test(YES);
}
return 0;
}
Когда я создаю и запускаю это с включенными объектами зомби, я получаю это сообщение об ошибке:
-[NSObject retain]: message sent to deallocated instance 0x100109100
Как я прокомментировал в коде, он отлично работает, если obj
ссылается каким-то другим способом, например, с помощью NSLog
или с помощью NSArray
. Я неправильно понял, как объекты выпущены с ARC и областями или это ошибка оптимизации в LLVM или Clang?
Я использую Xcode 4.5.2 с clang версии 4.1 (теги/Apple/clang-421.11.66) (на основе LLVM 3.1svn). Я могу воспроизвести его при создании для 64-разрядного x86 для iOS-симулятора и Mac OS X, и я уверен, что такая же проблема возникает при создании ARM, поскольку проблема была впервые обнаружена при запуске выпуска на iPhone.
Я опубликовал отчет об ошибке Apple и создал открытый радарный отчет.
Что, если что-нибудь, мне не хватает?
Обновить, сделал еще несколько экспериментов:
Как сказал Габро, компилятор переводит @[]
в оператор [NSArray arrayWithObjects:count:]
, поэтому я сделал несколько тестов:
// works
id a[] = {obj};
[NSArray arrayWithObjects:a count:1];
// does not work
const id *b = (id[]){obj};
[NSArray arrayWithObjects:b count:1];
// does not work
[NSArray arrayWithObjects:(id[]){obj} count:1];
Итак, я предполагаю, что это происходит при объединении ARC и анонимных массивов C.