合成属性时(见下文)
@interface CelestialBody : NSObject {
NSString *name;
}
...
@interface Planet : NSObject {
NSString *name;
int mass;
CelestialBody *moon;
}
@property(nonatomic, retain) NSString *name;
@property(assign) int *mass;
@property(nonatomic, retain) CelestialBody *moon;
...
@implementation Planet
@synthesize name;
@synthesize mass;
@synthesize moon;
...
你得到每个iVars的设定者和吸气剂(即)
[newPlanet setName:@"Jupiter"];
[newPlanet setMass:57];
NSString *closestName = [newPlanet name];
int largestMass = [newPlanet mass];
CelestialBody *newMoon = [[CelestialBody alloc] initWithName:@"Callisto"];
[self setMoon:newMoon];
[newMoon release];
但您也可以使用...
释放对象// Releases the object (frees memory) and sets the object pointer to nil.
[self setMoon: nil];
每个班级当然会有deallocs。
// Moon
-(void)dealloc {
[name release];
[super dealloc];
}
// Planet
-(void)dealloc {
[name release];
[moon release];
[super dealloc];
}
我说得对吗?
加里
答案 0 :(得分:2)
除非您的星球对象被声明为其他类中的属性,否则使用retain / copy属性,您无法以这种方式释放它。
使用retain / copy声明属性时,生成的setter将释放旧值并分配新值,在此过程中保留或复制它。如果你传递nil,你将释放旧值并指定nil,保留或复制它,并且保留/复制nil为nil,所以有效地你最终释放旧值并将nil分配给ivar。
这是发布实例变量的可接受方式。
为了能够以这种方式释放你的newPlanet实例,你必须在类中将它声明为具有retain或copy的属性。
作为另一个例子,由于你的星球对象以这种方式声明它的属性,你可以使用这种方法释放它们。
或者在Planet类的dealloc方法中,您可以这样做:
self.name = nil;
这将释放名称并为其指定nil。
答案 1 :(得分:1)
“你也能够释放对象”
是的,只要您没有使用assign
属性声明它。
您可能知道,使用声明属性的原因之一(尽管可能不是主要原因)是您可以这样做:
self.moon = aMoon;
而不是;
[self setMoon:aMoon];
它们是等价的。这意味着您的释放可能如下所示:
self.moon = nil; // Releases and sets to nil
但请记住,不要只做:
moon = nil; // Sets to nil, doesn't release
不仅要释放对象,而且要将变量设置为nil,这是非常好的做法,因为否则其他一些代码可能会错误地尝试使用变量中留下的指针。
答案 2 :(得分:0)
你的例子显示了一个类的ivars(Planet的那些)的合成,但是使用了另一个类(无论是“self”)。你最后一个例子中“self”的“newPlanet”属性是否也合成为(retain)?如果是这样,那么:是的,将newPlanet设置为nil将释放任何自己的旧“newPlanet”。
答案 3 :(得分:0)
我认为你做得不对。
更新问题后,是的,您可以这样做,并且:
self.moon = [[CelestialBody alloc] initWithName:@"Callisto"];
稍后发布,可能是你的dealloc方法:
self.moon = nil;
Apple Objective-c 2.0属性和内存管理文档相当不错。检查Mac开发中心库。