有人能告诉我NSString实例变量“planetName”是否需要由我分配/释放(如下例所示),还是在创建/分配类实例时完成?
我的理解是int和float不需要,但不确定NSString& NSArray ......
@interface PlanetClass : NSObject {
NSString *planetName;
}
- (NSString *)planetName;
- (void)setPlanetName:(NSString *)value;
@end
喜欢这个......
- (id) init {
[super init];
planetName = [[NSString alloc] init];
return self;
}
- (void) dealloc {
[planetName release];
[super dealloc];
}
** ---------------------------------- ** 编辑:编辑:这是另一个版本 ** ---------------------------------- **
int main(int argc, const char *argv[]) {
// ** Allocated here
PlanetClass *newPlanet_01 = [[PlanetClass alloc] init];
NSString *newPlanetName = [NSString alloc] init];
// ** Set the instance variable pointer here
newPlanetName = @"Jupiter";
[newPlanet_01 setPlanetName:newPlanetName];
// ** Released here
[newPlanet_01 release];
return 0;
}
初始& dealloc方法就像这样......
- (id) init {
[super init];
return self;
}
- (void) dealloc {
// Always release the current copy of planetName
// pointed to by the class instance.
[planetName release]
[super dealloc];
}
setPlanetName方法看起来像这样......
- (void)setPlanetName:(NSString *)newPlanetName {
if (planetName != newPlanetName) {
[planetName release];
planetName = [newPlanetName copy];
}
}
PS:我没有使用属性或合成,我还没有那么远。
欢呼 - 加里 -
答案 0 :(得分:3)
您的代码有效,但可能没有理由将planetName初始化为空字符串。 Objective-C的一个很好的功能是你可以将消息发送到一个没有任何后果的nil对象。如果您的类已初始化且您从未调用-setPlanetName:
,则planetName将为nil(实例变量始终初始化为nil
),因此当您的-dealloc
方法调用[planetName release]
时,会发生。
通常,最佳做法是在设置NSString实例变量时使用-copy
,在将大多数其他对象设置为实例变量时使用-retain
。因此,您的-setPlanetName:
方法看起来像这样:
- (void)setPlanetName:(NSString *)newPlanetName {
NSString *tempPlanetName = [newPlanetName copy];
[planetName release];
planetName = tempPlanetName;
}
答案 1 :(得分:1)
planetName是指针,与 int 或 float 一样,不需要分配或初始化。
就像你可以为int或float赋值,你可以将planetName指向字符串的不同实例,或者它可以指向任何内容。
当你开始上课时,planetName将是nil(不指向任何东西)。如果将planetName指向字符串的实例,则必须保留该字符串,并在dealloc中 release 。
换句话说,这个:
planetName = [[NSString alloc] init];
是不必要的,毫无意义。
在 setPlanetName 方法中,您需要释放 planetName指向的现有字符串,将planetName分配给新字符串,然后保留新字符串。
您的 dealloc 方法是正确的。
答案 2 :(得分:1)
您的新代码仍然存在问题。
在您的主要功能中,您释放newPlanetName
,但这有点不对劲。您的PlanetClass
用setPlanetName:
方法保留了它,但除非行星名称发生变化,否则PlanetClass
永远不会再发布它。不应该由setPlanetName:
的调用者来保持字符串,你的班级有责任妥善处理它。
您的旧dealloc
方法是正确的。它应该释放行星的名字,因为你的PlanetClass
不再需要它。你的主要方法不应该释放行星的名称,因为stringWithString:
返回的字符串不属于你,你将它交给PlanetClass
来处理。
因此,请保留旧的dealloc
方法,并从主要功能中移除[newPlanetName release]
,您应该可以从那里开始。
作为一种快捷方式,您甚至可以拨打[newPlanet_01 setPlanetName:@"Jupiter"]
并在主要功能中完全取消newPlanetName
变量。
答案 3 :(得分:0)
您的代码看起来不错。 NSObject
子类(包括NSString
)需要由拥有它们的对象管理其内存。在这种情况下,该所有者为PlanetClass
。