如何处理@synthesized保留属性的发布? [英] How is release handled for @synthesized retain properties?

查看:155
本文介绍了如何处理@synthesized保留属性的发布?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Objective-C中的合成属性有一些疑问。完整的列表如下,但基本的问题是:编译器如何确保合成属性的ivar正确发布,即使我的代码可能包括或不包括释放方法在dealloc?

I have some questions about synthesized properties in Objective-C. The full list follows, but the basic question is this: How does the compiler ensure that the ivars for synthesized properties are properly released, even though my code may or may not include release methods in dealloc?

注意:我决定不将这些问题发布为单独的问题,因为它们之间的关系非常密切,因为有几个现有的问题可以触摸

Note: I decided not to post these as individual questions because they are so closely related and because there are a handful of existing questions that touch on the individual issues without really getting to the heart of the matter.

有些类似的问题:

  • Does property retain need a release?
  • What's the difference between property and synthesize?
  • Question on retain attribute with property and synthesize

设置:具有单个属性:

@interface Person : NSObject
{
    NSString * name;
}
@property (nonatomic, retain) name;
@end






#1:非常基本的情况:

@implementation Person
@synthesize name;
@end



使用此设置,我假设 name 将在每次释放 Person 对象时自动释放。在我看来,编译器简单地将 [name release] 插入到 dealloc 方法中,就像我自己键入。是正确的吗?

With this setup, I assume that name will be automatically released whenever a Person object is released. In my mind, the compiler simply inserts [name release] into the dealloc method as if I had typed it myself. Is that correct?

问题2:如果我选择写我自己的 dealloc 方法,并且省略对 [name release] 的调用,会泄漏吗?

Question #2: If I choose to write my own dealloc method for this class, and I omit a call to [name release], will that leak?

@implementation Person
@synthesize name;
- (void)dealloc { [super dealloc]; }
@end






问题3:如果我选择为此类编写我自己的 dealloc 方法,并且包括 $ c> [name release] 会导致双重释放,因为 @synthesize 已经为我照顾了吗? / p>


Question #3: If I choose to write my own dealloc method for this class, and I include a call to [name release], will that result in a double-release, since @synthesize has already taken care of it for me?

@implementation Person
@synthesize name;
- (void)dealloc { [name release]; [super dealloc]; }
@end






问题#4:如果我选择为此类编写自己的属性访问器,但我不会编写自己的 dealloc 方法, name 是否会泄露?


Question #4: If I choose to write my own property accessor for this class, but I do not write my own dealloc method, will name be leaked?

@implementation Person
@dynamic name;
- (void)setName:(NSString *)newName
{
    [newName retain];
    [name release];
    name = newName;
}
@end






问题#5:我有一种感觉(根据经验),上述情况下的会导致泄漏或双重发布,因为语言设计为避免他们。这当然提出了如何?的问题。编译器是否足够聪明,足以跟踪所有可能的情况?如果我做了以下(如果这是一个可笑的例子,只是为了说明我的观点),如果我这样做:


Question #5: I have a feeling (based on experience) that none of the above scenarios will result in leaks or double-releases, since the language has been designed to avoid them. That, of course, raises the question of "how?". Is the compiler simply smart enough to keep track of every possible case? What if I were to do the following (note that this is a ludicrous example, just meant to illustrate my point):

void Cleanup(id object) { [object release]; }

@implementation Person
@synthesize name;
- (void)dealloc { Cleanup(name); }
@end

这会让编译器添加另一个 [name release] 到 dealloc 方法?

Would that fool the compiler into adding another [name release] to the dealloc method?

推荐答案

Q1:

否。 @synthesize 不会为您修改 -dealloc 。您必须 -release 姓名

No. @synthesize does not modify the -dealloc for you. You have to -release the name yourself.

Q2:

是的,它会泄漏。与Q1相同的原因。

Yes it will leak. Same reason as Q1.

Q3:

-发布。与Q1相同的原因。

No it won't double-release. Same reason as Q1.

Q4:

与Q1相同的原因。

Q5:

-发布。与第一季度相同。

No it won't double-release. Same reason as Q1.

您可以通过覆盖 -retain -release -dealloc 来报告发生了什么。

You can check this yourself by overriding -retain and -release and -dealloc to report what is going on.

#import <Foundation/Foundation.h>

@interface X : NSObject {}
@end
@implementation X
-(oneway void)release {
        NSLog(@"Releasing %p, next count = %d", self, [self retainCount]-1);
        [super release];
}
-(id)retain {
        NSLog(@"Retaining %p, next count = %d", self, [self retainCount]+1);
        return [super retain];
}
-(void)dealloc {
        NSLog(@"Dealloc %p", self);
        [super dealloc];
}
@end

@interface Y : NSObject {
        X* x;
}
@property (nonatomic, retain) X* x;
@end
@implementation Y
@synthesize x;
- (void)dealloc { [x release]; [super dealloc]; }
@end

int main () {
        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
        Y* y = [[Y alloc] init];
        X* x = [[X alloc] init];
        y.x = x;
        [y release];
        [x release];
        [pool drain];                                                    
        return 0;
}

在Q1,Q2和Q4,最后 x 的retainCount 为1,因此存在泄漏,在Q3和Q5中最后的 -retainCount 为0并且 -dealloc 被调用,因此没有泄漏。

In Q1, Q2 and Q4, the last -retainCount of x is 1, so there is a leak, and in Q3 and Q5 the last -retainCount is 0 and -dealloc is called, so there is no leak.

这篇关于如何处理@synthesized保留属性的发布?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆