是否会自动发布相关对象?

时间:2021-11-08 09:42:23

Note: This other question seems relevant but it's not: When does an associated object get released?

注意:这个问题似乎很相关,但事实并非如此:关联对象什么时候发布?

I'm adding a second description to a UIView instance as follows:

我正在向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);   
}

If the UIView deallocs, will the associated description 2 get dealloced? Is there any way to get this to happen automatically?

如果UIView deallocs,相关描述2是否会被解除分配?有没有办法让这种情况自动发生?

4 个解决方案

#1


62  

If you want to actually see the description of the entire dealloc timeline, look at WWDC 2011, Session 322, 36:22. However, here's the basic rundown (I wanted to remember it, so this is an actual comment in a piece of my code).

如果您想要实际查看整个dealloc时间轴的描述,请查看WWDC 2011,Session 322,36:22。但是,这是基本的纲要(我想记住它,所以这是我的代码中的实际注释)。

Note, that the associated objects are released at the end of the life cycle.

请注意,关联对象在生命周期结束时释放。

// 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


3  

Yes. When an object is dealloc'd, any associated objects (that use the RETAIN or COPY association types) are automatically released.

是。取消分配对象时,将自动释放任何关联的对象(使用RETAIN或COPY关联类型)。

#3


3  

In short, yes - when the owning object is released then retained associated objects are released. See the first section of Apple's documentation

简而言之,是 - 当释放拥有对象时,释放保留的关联对象。请参阅Apple文档的第一部分

#4


0  

Section 4 in Jody Hagins' answer says "Erase associated references", which doesn't explicitly imply that the references are released. So I used the following piece of code (note WITHOUT ARC) to test this.

Jody Hagins的第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];
}

Invoking above code does indeed end up calling -[AssociatedObjectHelper dealloc], with the following stack-trace:

调用上面的代码确实最终调用 - [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]

Tested on Xcode 7.0.1

在Xcode 7.0.1上测试过

#1


62  

If you want to actually see the description of the entire dealloc timeline, look at WWDC 2011, Session 322, 36:22. However, here's the basic rundown (I wanted to remember it, so this is an actual comment in a piece of my code).

如果您想要实际查看整个dealloc时间轴的描述,请查看WWDC 2011,Session 322,36:22。但是,这是基本的纲要(我想记住它,所以这是我的代码中的实际注释)。

Note, that the associated objects are released at the end of the life cycle.

请注意,关联对象在生命周期结束时释放。

// 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


3  

Yes. When an object is dealloc'd, any associated objects (that use the RETAIN or COPY association types) are automatically released.

是。取消分配对象时,将自动释放任何关联的对象(使用RETAIN或COPY关联类型)。

#3


3  

In short, yes - when the owning object is released then retained associated objects are released. See the first section of Apple's documentation

简而言之,是 - 当释放拥有对象时,释放保留的关联对象。请参阅Apple文档的第一部分

#4


0  

Section 4 in Jody Hagins' answer says "Erase associated references", which doesn't explicitly imply that the references are released. So I used the following piece of code (note WITHOUT ARC) to test this.

Jody Hagins的第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];
}

Invoking above code does indeed end up calling -[AssociatedObjectHelper dealloc], with the following stack-trace:

调用上面的代码确实最终调用 - [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]

Tested on Xcode 7.0.1

在Xcode 7.0.1上测试过