ios - Objective-C 对象能否在其方法中删除自身(启用 ARC)?

标签 ios objective-c macos

由于某些原因,我不得不使用对象从其容器中移除自身的设计模式,考虑以下代码(启用ARC,LCDObject是一个对象类,LCDContainer是一个容器类),在整个程序中, object 的引用计数一直为 1,直到它被从容器中移除(引用计数变为 0),正如评论 2 提到的,当 [_container removeObject:self] 返回时,对象的引用计数为 0,是dealloc吧下面的代码能成功执行吗? "removeFromContainer"是否能成功返回?

我在Xcode中运行这段代码,可以成功调用“removeFromContainer”中的“NSLog”,但我不明白为什么...

//-------------------------------------------------------------
#import <Foundation/Foundation.h>

@interface LCDContainer : NSObject

@property (strong, nonatomic) NSMutableArray *objects;
- (void)removeObject:(id)object;
- (id)addObject:(id)object;

@end

@implementation LCDContainer

- (id)init {
    self = [super init];
    if (self) {
        _objects = [[NSMutableArray alloc] init];
    }
    return self;
}

- (id)addObject:(id)object {
    [_objects addObject:object];
    return object;
}

- (void)removeObject:(id)object {
    [_objects removeObject:object];
}

@end

//-------------------------------------------------------------
@interface LCDObject : NSObject

@property (weak, nonatomic) LCDContainer *container;
- (id)initWithContainer:(LCDContainer*) container;
- (void)removeFromContainer;

@end

@implementation LCDObject

- (id)initWithContainer:(LCDContainer *)container {
    self = [super init];
    if (self) {
        _container = container;
        // (1) add the object to the Container, now its reference count is 1
        //
        [container addObject:self];
        NSLog(@"add to container.");
    }
    return self;
}

- (void)removeFromContainer {
    // (2) remove the object from the Container, now its reference count is 0,
    //     the object is delete, does the following "NSLog" would be invoked successfully? 
    //
    [_container removeObject:self];
    NSLog(@"remove from container.");
}

@end

//-------------------------------------------------------------
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        LCDContainer *container = [[LCDContainer alloc] init];
        [[LCDObject alloc] initWithContainer:container];
        [[[container objects] objectAtIndex:0] removeFromContainer];
    }
    return 0;
}

最佳答案

我没有尝试过您的代码,但我怀疑它会起作用。不过,sapi 的建议(在 dealloc 上添加断点或 NSLog)是一个很好的确认。

ARC 可以通过两种方式做到这一点。如果您真的感兴趣,可以查看汇编器。

最简单的是假设它正在使用autorelease,也就是说,当一个对象从你的容器中移除时,它会被添加到自动释放池中,并在结束时被释放(和释放)当前运行循环。

另一种方法是考虑 ARC 添加其保留和释放的位置This question请注意,您的删除方法确实如下所示:

- (void)removeObject:(id)object {
    [object retain];
    [_objects removeObject:object];
    [object release];
}

调用 removeObject: 可能具有相同的逻辑。这意味着对象不会在 removeObject: 调用完成后立即释放;对象生命周期几乎肯定(略)长于此。

关于ios - Objective-C 对象能否在其方法中删除自身(启用 ARC)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25237079/

相关文章:

objective-c - 我应该使用 merge=union 将 .pbxproj 文件与 git merge 吗?

iphone - Objective-C 中的内存管理

xcode - 如何将 "Run Script"构建阶段限制为我的发布配置?

ios - 在不使用 MFMailComposeViewController 的情况下从我的应用程序发送电子邮件

ios - Swift 3 迁移后无法在调试器中查看变量值

ios - 编写单元测试以验证 NSTimer 是否已启动

ios - Paypal iOS SDK 无 View Controller

macos - 我们如何使用 opendirectory 在 mac 中缓存 ldap 登录凭据

windows - Windows 和 Mac OS X 之间的字体大小

ios 自动布局自动调整大小不起作用