Будет ли связанный объект выпущен автоматически?
Примечание: этот другой вопрос кажется актуальным, но это не так: когда связанный объект освобождается?
Я добавляю второе описание к UIView
пример следующим образом:
- (void) setSecondDescription:(UIView*)view description2:(NSString*)description2 {
objc_setAssociatedObject (view,&key,description2,OBJC_ASSOCIATION_RETAIN);
}
- (NSString*) secondDescription:(UIView*)view {
return (id)objc_getAssociatedObject(view, &key);
}
Если UIView
deallocs, будет ли связанное описание 2 освобождено? Есть ли способ, чтобы это произошло автоматически?
4 ответа
Если вы хотите увидеть описание всей временной шкалы dealloc, посмотрите WWDC 2011, Session 322, 36:22. Тем не менее, вот основное краткое изложение (я хотел запомнить это, так что это фактический комментарий в части моего кода).
Обратите внимание, что связанные объекты освобождаются в конце жизненного цикла.
// General Information
// We take advantage of the documented Deallocation Timeline (WWDC 2011, Session 322, 36:22).
// 1. -release to zero
// * Object is now deallocating and will die.
// * New __weak references are not allowed, and will get nil.
// * [self dealloc] is called
// 2. Subclass -dealloc
// * bottom-most subclass -dealloc is called
// * Non-ARC code manually releases iVars
// * Walk the super-class chain calling -dealloc
// 3. NSObject -dealloc
// * Simply calls the ObjC runtime object_dispose()
// 4. object_dispose()
// * Call destructors for C++ iVars
// * Call -release for ARC iVars
// * Erase associated references
// * Erase __weak references
// * Call free()
Да. Когда объект освобождается, любые связанные объекты (которые используют RETAIN
или же COPY
типы ассоциации) автоматически освобождаются.
Короче говоря, да - когда объект-владелец освобождается, освобождаются связанные объекты. Смотрите первый раздел документации Apple
Раздел 4 в ответе Джоди Хагинс гласит "Стереть связанные ссылки", что явно не означает, что ссылки выпущены. Поэтому я использовал следующий фрагмент кода (обратите внимание, без дуги), чтобы проверить это.
@interface AssociatedObjectHelper : NSObject
@end
@implementation AssociatedObjectHelper
- (void) dealloc
{
NSLog(@"In %s", __FUNCTION__);
[super dealloc];
}
@end
@implementation AppDelegate
...
- (void) testReleaseAssociatedObject
{
static const NSString *key = @"testKey123";
NSObject *ob = [NSObject new];
AssociatedObjectHelper *assocOb = [AssociatedObjectHelper new];
objc_setAssociatedObject(ob, key, assocOb, OBJC_ASSOCIATION_RETAIN);
[assocOb release];
[ob release];
}
Вызов приведенного выше кода действительно в конечном итоге вызывает -[AssociatedObjectHelper dealloc] со следующей трассировкой стека:
#0 0x000000010000528f in -[AssociatedObjectHelper dealloc]
#1 0x00007fff8a0bb89c in objc_object::sidetable_release(bool) ()
#2 0x00007fff8a0a537f in _object_remove_assocations ()
#3 0x00007fff8a0a1644 in objc_destructInstance ()
#4 0x00007fff8a0a1595 in object_dispose ()
#5 0x00007fff8a0bb89c in objc_object::sidetable_release(bool) ()
#6 0x000000010000e9b6 in -[AppDelegate testReleaseAssociatedObject]
Протестировано на Xcode 7.0.1