由于某些原因,我不得不使用对象从其容器中移除自身的设计模式,考虑以下代码(启用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/