В Clang Objective-C Автоматический подсчет ссылок мы видим следующее
Для объектов __weak значение lvalue обновляется, чтобы указать на нового pointee, если новый pointee не является объектом, который в настоящее время проходит освобождение, и в этом случае lvalue обновляется до нулевого указателя. Это должно выполняться атомарно по отношению к другим назначениям объекту, чтению с объекта и окончательному выпуску нового указателя.
В objc-weak.mm мы видим следующий фрагмент кода в weak_register_no_lock()
:
if (deallocating) {
if (crashIfDeallocating) {
_objc_fatal("Cannot form weak reference to instance (%p) of "
"class %s. It is possible that this object was "
"over-released, or is in the process of deallocation.",
(void*)referent, object_getClassName((id)referent));
} else {
return nil;
}
}
Я установил точку останова в моем подклассе UIViewController dealloc
и попытался вызвать [self allowsWeakReference]
в lldb, что привело к значению NO
.
Если мы попытаемся задать себе слабое свойство другого объекта, приложение будет разбиваться в соответствии с кодом objc-weak.mm.
Вопрос: почему это происходит? Является ли спецификация clang неправильной? Является ли это ошибкой в реализации objc?Вот простой фрагмент кода, который воспроизведет сбой:
//cc -fmodules -fobjc-arc -g crash.m -o crash
@import Foundation;
@interface Foo : NSObject
@end
@implementation Foo
- (void)dealloc {
Foo * __weak weakSelf = self; // crashes on this line
}
@end
int main() {
(void)[[Foo alloc] init];
return 0;
}