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

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

问题描述

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

注意:我决定不将这些作为单独的问题发布,因为它们是如此密切相关,并且因为有一些现有问题触及个别问题而没有真正触及问题的核心很重要.

有些类似的问题:

<小时>

设置:考虑一个具有单一属性的类:

@interface 人:NSObject{NSString * 名称;}@property(非原子,保留)名称;@结尾

<小时>

问题 1: 非常基本的情况:

@implementation Person@合成名称;@结尾

通过这个设置,我假设只要 Person 对象被释放,name 就会自动释放.在我看来,编译器只是将 [name release] 插入到 dealloc 方法中,就好像我自己输入一样.对吗?

<小时>

问题 2:如果我选择为这个类编写自己的 dealloc 方法,并且省略对 [name release],会不会泄露?

@implementation Person@合成名称;- (void)dealloc { [超级dealloc];}@结尾

<小时>

问题 #3:如果我选择为这个类编写自己的 dealloc 方法,并且我包括 的调用[name release],这样会不会导致双重释放,因为@synthesize 已经帮我处理好了?

@implementation Person@合成名称;- (void)dealloc { [名称发布];[超级dealloc];}@结尾

<小时>

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

@implementation Person@动态名称;- (void)setName:(NSString *)newName{[新名称保留];[名称发布];名称 = 新名称;}@结尾

<小时>

问题 #5:我有一种感觉(根据经验) 上述情况都不会导致泄漏或双重发布,因为语言已经旨在避免它们.当然,这提出了如何?"的问题.编译器是否足够聪明以跟踪每种可能的情况?如果我要执行以下操作怎么办(请注意,这是一个荒谬的例子,只是为了说明我的观点):

void Cleanup(id object) { [object release];}@实施人员@合成名称;- (void)dealloc { Cleanup(name);}@结尾

这会欺骗编译器在 dealloc 方法中添加另一个 [name release] 吗?

解决方案

Q1:

没有.@synthesize 不会为您修改 -dealloc.你必须自己-releasename.

第二季度:

是的,它会泄漏.与第一季度相同的原因.

Q3:

不,它不会双重发布.与第一季度相同的原因.

第 4 季度:

是的,它会泄漏.与第一季度相同的原因.

问题 5:

不,它不会双重发布.与第一季度相同的原因.

<小时>

您可以通过覆盖 -retain-release-dealloc 来报告正在发生的事情.

#import @interface X : NSObject {}@结尾@实施X-(单向无效)释放{NSLog(@"Releasing %p, next count = %d", self, [self retainCount]-1);【超级发布】;}-(id)保留{NSLog(@"Retaining %p, next count = %d", self, [self retainCount]+1);return [超级保留];}-(无效)dealloc {NSLog(@"Dealloc %p", self);[超级dealloc];}@结尾@interface Y : NSObject {X* X;}@property (nonatomic, 保留) X* x;@结尾@实现Y@合成 x;- (void)dealloc { [x release];[超级dealloc];}@结尾int主(){NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];Y* y = [[Y alloc] init];X* x = [[X 分配] init];y.x = x;[y 发布];[x 发布];[池排水];返回0;}

在Q1、Q2和Q4中,x的最后一个-retainCount为1,所以存在泄漏,而在Q3和Q5中最后一个-retainCount 为 0 并且 -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.

Somewhat similar questions:


Setup: Consider a class with a single property:

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


Question #1: The very basic case:

@implementation Person
@synthesize name;
@end

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?


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


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


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


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

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

解决方案

Q1:

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

Q2:

Yes it will leak. Same reason as Q1.

Q3:

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

Q4:

Yes it will leak. Same reason as Q1.

Q5:

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


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;
}

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天全站免登陆