假设我有一个界面:
@interface it:NSObject
{
NSString* string;
}
@end
@implement it
-(id)init
{
if(self = [super init]){
self.string = [[NSString alloc]init];
}
}
-(void)dealloc
{
[self.string release];
[super release];
}
@end
如果我在另一个文件中使用此类,我称之为:
it ait = [[it allow] init];
NSString* anotherString = [[NSString alloc] init];
ait.string = anotherString;
[anotherString release];
这会导致在init方法中分配的字符串内存泄漏吗? 由于字符串未被引用而未自动释放。 如果我没有在init方法中分配一个字符串,那么当我在向它分配anotherString之前调用ait.string时会发生什么?
答案 0 :(得分:1)
我认为你需要
@property (nonatomic, retain) NSString *string;
在您的界面中
@synthesize string;
在你的实现中使用self.string。
然后,当你做
self.string = [[NSString alloc] init];
在你的init方法中,字符串的实际保留计数为2,因为[[NSString alloc] init]
将返回一个保留计数为1的字符串,并且使用self.string =
将再次保留该对象,因为该属性是宣称为“保留”。这将导致内存泄漏,但您可以通过:
-(id)init
{
if(self = [super init]){
self.string = @"initString";
}
}
或类似。
然后,在实际问题上,如果你按照上面的方式执行,当你用self.string =
重新分配时,init中分配的字符串不会泄漏,因为标记为'retain'的属性会在保留新对象之前释放它们的当前对象。
如果你没有在init方法中为self.string
分配一个字符串,那就无所谓了,因为self.string
只返回nil
,你可以在你的程序中处理它
答案 1 :(得分:0)
@interface it:NSObject
{
NSString* string;
}
//you should declare a property in order to call it with 'self' prefix
@property (nonatomic, retain) NSString* string;
@end
@implementation it
//you should synthesize your property
@synthesize string;
-(id)init
{
if(self = [super init]){
//you don't to initialize NSString right here (memory leak will have place)
//self.string = [[NSString alloc]init];
//you can store a default value like this (can be omitted):
self.string = @"Default value";
}
return self;
}
-(void)dealloc
{
[self.string release];
[super release];
}
@end
关于本课程内存管理的一切都会没问题。
答案 2 :(得分:0)
这是否会导致分配的字符串 init方法有内存泄漏吗?以来 字符串未被引用而不是 自动释放。
是的,确切地说。你似乎已经得到了它。
如果我没有在init中分配字符串 方法,我打电话会发生什么 在分配之前的ait.string 它的另一个字符串?
你的意思是在下面的例子中你不确定unknownObject会引用什么?: -
It *ait = [[It allow] init];
NSString *unknownObject = ait.string;
这是胡说八道。您是否忘记添加访问者方法?
Objective-c不使用“点语法”来访问实例变量,例如Java。如果你有一个类'it'的实例,你只能通过调用accessor'getter'方法从该实例外部访问'string'变量。这不是可选的self.string只是方法调用[self string]的快捷方式,并且在您显示的代码中不存在此方法。
假设访问器方法在别处定义,您调用字符串的实例变量(这是世界上最差的变量名称)等于 nil 。在Objective-c中,您必须非常小心地处理nil对象,因为行为与其他语言处理相似的 null 的行为不同。
在Objective-c中,这很好:
NSString *nilString = nil;
[nilString writeToFile:@"/this_file_cannot_exist.data"];
许多其他语言会在这里崩溃或抛出异常;这可能很危险,因为操作可能会失败但您的应用程序将继续运行。它也可能很棒,因为在其他语言中你会看到很多这个......
someObject = controller.currentValue()
if( someObject!=null )
someObject.writeToFile("myFile.data")
在Objective-c中,根本不需要'if(..)'行。
您必须注意不要在init和dealloc方法中调用访问器方法,因为这会破坏子类。而不是
- (void)dealloc {
[self.string release]; // This is [[self string] release]
...
你应该使用
- (void)dealloc {
[string release];
...
除了危险之外,对[self string]的调用是不必要的。在init方法中也是如此
if(self=[super init]){
self.string = [[NSString alloc]init]; // shortcut for [self setString:[[NSString alloc] init]]
...
只需使用
if(self=[super init]){
string = [[NSString alloc] init];
...
答案 3 :(得分:0)
你错过了@property才能使用self.string。
将此添加到您的.h文件
@property (readwrite, copy) NSString *string;
使用Copy而不是Retain将阻止字符串内存泄漏,即使你释放了另一个字符串。