OC 内存管理问题
最近学习 OC 内存管理遇到个问题
main.m
int main(int argc, const char * argv[]) {
Person *p1 = [[Person alloc] init];
Person *p2 = [[Person alloc] init];
Dog *d = [[Dog alloc] init];
p1.dog = d;
p2.dog = d;
[d release];
p1.dog = nil;
p2.dog = nil;
return 0;
}
Dog.m
@implementation Dog
- (void)dealloc
{
NSLog(@"Dog 被销毁了");
[super dealloc];
}
@end
Person.h
@class Dog;
@interface Person : NSObject
@property(retain) Dog *dog;
@end
上面的代码运行后,可以打印出 Dog 被销毁了
。但是如果把 main.m 改成下面的代码就没有打印了。
int main(int argc, const char * argv[]) {
Person *p1 = [[Person alloc] init];
Person *p2 = [[Person alloc] init];
Dog *d = [[Dog alloc] init];
p1.dog = d;
p2.dog = p1.dog; // 只改了这一行
[d release];
p1.dog = nil;
p2.dog = nil;
return 0;
}
感觉这个问题可能和内存管理没什么关系,可能是变量引用的问题,初学 OC 希望大佬们指点下~
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题应该出在这里
dog属性声明为了atomic类型,为了保证原子性,dog的set和get方法应该做过处理。
我感觉mrc下的atomic属性的set和get方法应该类似下面这样实现。
所以在调用
p2.dog = p1.dog;
的时候,会先调用get方法(p1.dog),内部会先对dog retain一次,引用计数+1, 然后放进自动释放池,在调用set(p2.dog)时,又会retain一次。所以这一句代码引用计数其实是+2了, 所以最后在release和nil之后,引用计数仍然为1,不会释放。按道理说在get里面+1的那一次应该被减回去的,但是因为main方法中的autoreleasepool被删掉了,所以标记的autorelease没有起到作用。
综上,atomic的get方法中为了安全多+1并没有被autorelease掉,所以导致引用计数无法被置0,属性无法释放,也就不会打印dealloc.