Будет ли выпущен ассоциированный объект автоматически?

Примечание. Этот другой вопрос кажется актуальным, но это не так: Когда вызывается связанный объект?

Я добавляю второе описание к экземпляру 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? Есть ли способ, чтобы это произошло автоматически?

Ответ 1

Если вы хотите на самом деле видеть описание всей временной шкалы 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()

Ответ 2

Да. Когда объект dealloc'd, любые связанные объекты (которые используют типы связей RETAIN или COPY) автоматически освобождаются.

Ответ 3

Короче говоря, да - когда освобождается принадлежащий ему объект, сохраняются связанные объекты. См. Первый раздел Apple documentation

Ответ 4

В разделе 4 в ответе ответа Джоди Хагин говорится: "Удалите связанные ссылки", в котором явно не указано, что ссылки выпущены. Поэтому я использовал следующий фрагмент кода (примечание WITHOUT ARC), чтобы проверить это.

@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