我对 Objective-C 中的综合属性有一些疑问.完整列表如下,但基本问题是:编译器如何确保合成属性的 ivars 被正确释放,即使我的代码可能包含也可能不包含在 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.
有些类似的问题:
设置:考虑一个具有单个属性的类:
Setup: Consider a class with a single property:
@interface Person : NSObject
{
NSString * name;
}
@property (nonatomic, retain) name;
@end
<小时>
问题 #1: 非常基本的案例:
@implementation Person
@synthesize name;
@end
使用此设置,我假设只要释放 Person
对象,就会自动释放 name
.在我看来,编译器只是将 [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
方法,并且我包含一个对 的调用[name release]
,这会导致双重发布吗,因为 @synthesize
已经为我处理好了?
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
这会欺骗编译器向 dealloc
方法添加另一个 [name release]
吗?
Would that fool the compiler into adding another [name release]
to the dealloc
method?
Q1:
没有.@synthesize
不会为您修改 -dealloc
.你必须自己-release
name
.
No. @synthesize
does not modify the -dealloc
for you. You have to -release
the name
yourself.
第二季度:
是的,它会泄漏.原因与第一季度相同.
Yes it will leak. Same reason as Q1.
第三季度:
不,它不会双重释放.原因与第一季度相同.
No it won't double-release. Same reason as Q1.
第四季度:
是的,它会泄漏.原因与第一季度相同.
Yes it will leak. Same reason as 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 保留属性的释放是如何处理的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!