当 iOS 内存管理释放给定对象时,释放过程是否通过 setter 方法将它可能具有的任何属性的实例变量归零?
user1951992
问问题
197 次
2 回答
3
不,我们可以使用以下程序进行实验验证:
#import <Foundation/Foundation.h>
@interface CVObject : NSObject
@property (nonatomic) NSNumber *number;
@end
@implementation CVObject
- (void)setNumber:(NSNumber *)number
{
NSLog(@"setting number to %@", number);
_number = number;
}
- (void)dealloc
{
NSLog(@"deallocating");
}
@end
void doSomething()
{
CVObject *object = [[CVObject alloc] init];
object.number = @3;
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
doSomething();
}
return 0;
}
运行时的输出是:
setting number to 3
deallocating
通过向类添加另一个类型的属性CVObject*
,并在 dealloc 中放置一个断点,我们可以观察到第二个对象释放时的堆栈跟踪:
* thread #1: tid = 0x2203, 0x0000000100001a77 DoesDeallocUseProperties`-[CVObject dealloc](self=0x0000000102501da0, _cmd=0x00007fff934f508b) + 23 at main.m:36, stop reason = breakpoint 1.1
frame #0: 0x0000000100001a77 DoesDeallocUseProperties`-[CVObject dealloc](self=0x0000000102501da0, _cmd=0x00007fff934f508b) + 23 at main.m:36
frame #1: 0x0000000100001b4a DoesDeallocUseProperties`-[CVObject .cxx_destruct](self=0x0000000100103510, _cmd=0x000f6a00000f6a00) + 90 at main.m:20
frame #2: 0x00007fff90030fcc libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 100
frame #3: 0x00007fff9002a922 libobjc.A.dylib`objc_destructInstance + 91
frame #4: 0x00007fff9002afa0 libobjc.A.dylib`object_dispose + 22
frame #5: 0x0000000100001aa4 DoesDeallocUseProperties`-[CVObject dealloc](self=0x0000000100103510, _cmd=0x00007fff934f508b) + 68 at main.m:37
frame #6: 0x0000000100001c5c DoesDeallocUseProperties`doSomething + 268 at main.m:48
frame #7: 0x0000000100001c94 DoesDeallocUseProperties`main(argc=1, argv=0x00007fff5fbffa80) + 36 at main.m:54
frame #8: 0x00007fff951997e1 libdyld.dylib`start + 1
从跟踪中可以清楚地看出,没有使用任何属性设置器或获取器。
现在,为什么会这样?了解属性和实例变量没有内在联系很重要。名称可以独立变化。name
例如,拥有一个名为 的属性和一个实例变量_name
,并为此实现设置器和访问器是完全合法的,而这些设置器和访问器name
实际上并不涉及实例变量_name
。如果 ARC 依赖于属性,那么这种情况将是灾难性的。
于 2013-09-14T08:01:23.783 回答
1
不,它简单地向所有实例变量发送释放消息。
这可以通过一个简单的测试来观察,假设myProp
是一个强属性:
-(void)dealloc
{
NSLog(@"deallocing");
}
-(void)setMyProp:(MyClass *)prop
{
NSLog(@"setting my prop: %@", prop);
}
您将看到该setMyProp:
方法没有因为释放而被调用。
setMyProp:
理论上,您可以从被覆盖的方法手动调用,dealloc
但建议谨慎行事:Calling a method on self while in dealloc
于 2013-09-14T08:07:53.707 回答