首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >内存管理和属性(init/dealloc)

内存管理和属性(init/dealloc)
EN

Stack Overflow用户
提问于 2013-02-08 14:09:40
回答 4查看 116关注 0票数 0

直到昨天,我还以为我理解了属性内存管理是如何工作的,但是后来我用XCode运行了一个“分析”任务,得到了大量的“这个对象不在这里”。下面是一个简单的例子,描述了我的问题:

My观测站Object.h:

代码语言:javascript
运行
复制
@interface MyObservingObject : NSObject
@property(nonatomic, retain) NSMutableDictionary *observedDictionary;
-(id)initWithDictCapacity:(int)capacity;
@end

My观测站Object.m:

代码语言:javascript
运行
复制
@synthesize observedDictionary;

-(id)initWithDictCapacity:(int)capacity {
    self = [super init];
    if (self) {
        self.observedDictionary = [[[NSMutableDictionary alloc] initWithCapacity:capacity] autorelease];
    }
    return self;
}

- (void)dealloc {
    // The following line makes the Analize action say :
    // "Incorrect decrement of the reference count of an object that is not owned at this point by the caller"
    [self.observedDictionary release], self.observedDictionary=nil;

    [super dealloc];
}

我不明白的是,为什么要离开这个属性而不调用 release 呢? My @property被设置为retain (copy也是这样做的),所以当我做self.myRetainProperty = X时,X的保留数增加了(它是属于自己的),不是吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-02-08 14:14:47

它确实增加了,但是当您将它设置为nil时,setter方法首先释放支持实例变量,然后它才保留和分配新值。因此,将属性设置为nil就足够了,但是将ivar设置为nil会泄漏内存。

为了更好地理解:自动生成的保留setter的典型实现相当于以下内容

代码语言:javascript
运行
复制
- (void)setFoo:(id)foo
{
    if (_foo != foo) {
        [_foo release];
        _foo = [foo retain];
    }
}

另外,请注意,因此,您永远不应该发布这样的属性。如果这样做,可能会将背景ivar释放,并且消息传递它(访问器在将属性设置为release之后由访问器发出消息)可能会崩溃。

票数 1
EN

Stack Overflow用户

发布于 2013-02-08 14:14:08

您应该让setter为您执行发布,因此删除对releasedealloc调用。

代码语言:javascript
运行
复制
- (void)dealloc {
    self.observedDictionary=nil;

    [super dealloc];
}

这是因为设置者将被简化为以下内容:

代码语言:javascript
运行
复制
- (void)setObject:(id)object
{
    [object retain];
    [_object release];
    _object = object;
}

当您传入nil时,它将按需要工作。

票数 2
EN

Stack Overflow用户

发布于 2013-02-08 14:13:29

你不需要做

代码语言:javascript
运行
复制
[self.observedDictionary release]

在此之前

代码语言:javascript
运行
复制
self.observedDictionary=nil;

这就足够了,因为这是一个属性,它将自动将发布发送到以前的值。

代码语言:javascript
运行
复制
self.observedDictionary=nil;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14774394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档