Objective c 实例变量的分配?
有人能告诉我NSString实例变量“planetName”是否需要由我分配/释放(如下例所示),还是在创建/分配类实例时完成 我的理解是int和float不需要,但不确定NSString和NSArrayObjective c 实例变量的分配?,objective-c,memory,Objective C,Memory,有人能告诉我NSString实例变量“planetName”是否需要由我分配/释放(如下例所示),还是在创建/分配类实例时完成 我的理解是int和float不需要,但不确定NSString和NSArray @interface PlanetClass : NSObject { NSString *planetName; } - (NSString *)planetName; - (void)setPlanetName:(NSString *)value; @end 像这样 -
@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];
}
- (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];
}
- (void)setPlanetName:(NSString *)newPlanetName {
if (planetName != newPlanetName) {
[planetName release];
planetName = [newPlanetName copy];
}
}
**--------------------------------------**
编辑:编辑:这是另一个版本
**--------------------------------------**
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;
}
init&dealloc方法将如下所示
- (id) init {
[super init];
planetName = [[NSString alloc] init];
return self;
}
- (void) dealloc {
[planetName release];
[super 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];
}
- (void)setPlanetName:(NSString *)newPlanetName {
if (planetName != newPlanetName) {
[planetName release];
planetName = [newPlanetName copy];
}
}
setPlanetName方法将如下所示
- (id) init {
[super init];
planetName = [[NSString alloc] init];
return self;
}
- (void) dealloc {
[planetName release];
[super 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];
}
- (void)setPlanetName:(NSString *)newPlanetName {
if (planetName != newPlanetName) {
[planetName release];
planetName = [newPlanetName copy];
}
}
附言:我没有使用属性或合成,我还没有做到这一点
干杯-gary-您的代码是有效的,但可能没有理由将planetName初始化为空字符串。Objective-C的一个很好的特性是,您可以向nil对象发送消息,而不会产生任何后果。如果您的类已初始化,并且您从未调用
-setPlanetName:
,planetName将为nil(实例变量始终初始化为nil
),因此当您的-dealoc
方法调用[planetName release]
时,将不会发生任何事情
通常,最佳做法是在设置NSString实例变量时使用-copy
,在将大多数其他对象设置为实例变量时使用-retain
。因此,您的-setPlanetName:
方法如下所示:
- (void)setPlanetName:(NSString *)newPlanetName {
NSString *tempPlanetName = [newPlanetName copy];
[planetName release];
planetName = tempPlanetName;
}
你的代码看起来不错
NSObject
子类(NSString
包括在内)需要由拥有它们的对象管理它们的内存。在这种情况下,所有者是PlanetClass
planetName是一个指针,它与int或float一样,不需要分配或初始化
就像可以为int或float赋值一样,可以将planetName指向字符串的不同实例,也可以不指向任何对象
初始化类时,planetName将为nil(不指向任何对象)。如果将planetName指向字符串的实例,则必须保留该字符串,并在dealloc中释放
换言之,这:
planetName = [[NSString alloc] init];
没有必要,也没有意义
在setPlanetName方法中,需要释放planetName指向的现有字符串,将planetName分配给新字符串,然后保留新字符串
您的dealloc方法是正确的。您的新代码仍然存在问题 在main函数中,您发布了
newPlanetName
,但这有点错误。你的PlanetClass
用它的setPlanetName:
方法保留了它,但是你的PlanetClass
永远不会释放它,除非行星的名称改变。setPlanetName:
的调用者不应掌握字符串,而应由您的类负责适当地处理它
您以前的dealloc
方法是正确的。它应该公布行星的名称,因为你的PlanetClass
不再需要它。您的main方法不应释放行星的名称,因为stringWithString:
返回的字符串不属于您,您将其交给PlanetClass
处理
因此,保留旧的dealloc
方法,并从主函数中删除[newPlanetName release]
,这样您就不会有问题了
作为一种快捷方式,您甚至可以调用
[newPlanet\u 01 setPlanetName:@“Jupiter”]
并在主函数中完全删除newPlanetName
变量。ThatNSString*newPlanetName=[NSString alloc]init]
只是一个内存泄漏,因为您会立即为变量分配不同的NSString,而不会释放旧值。并非所有对象都初始化为nil,只有实例变量。在堆栈上创建的对象指针仍处于未初始化状态。您应该使用concider将planetName设置为@property(非原子,复制)。我可以理解为什么需要将[planetName release]添加到dealloc方法中。因此,当类被释放时,newPlanet的当前复制版本将被释放。我对newPlanetName有点困惑,因为我分配内存,然后分配“Jupiter”,我的印象是newPlanet需要被释放(上面的代码被修改),这是一个常见的误解。主函数中的newPlanetName
变量是指向对象的指针。使用[[NSString alloc]init]
时,只需分配并初始化一个空字符串,newPlanetName
变量指向该空字符串。当你给它赋值时,比如@“Jupiter”
,你改变了newPlanetName
指向的位置,事实上,它指向的原始对象(空字符串)现在不再是可访问的。这就是我想的。。。()newPlanetName是指向字符串对象的指针,最初它指向nil。()newPlanetName=@“Jupiter”将指针设置为指向字符串文本,我认为您不需要释放字符串文本,所以这很好。但是如果newPlanetName=someOtherStringObject,那么它指向的是一个实际的对象,那么我应该发布newPlanetName吗,或者这是某个其他StringObject的所有者的工作,可能是我,所以我需要执行[someOtherStringObject发布]?你的方向肯定是正确的。关于不需要释放文本字符串,您是对的,但是关于释放其他对象,这完全是关于如何获得它们。如果该方法包含单词“new”、“alloc”或“copy”,则您负责发布该方法。还有一些其他实例需要显式释放,但您应该查看Cocoa内存管理文档以了解更多信息。