2011-09-12 63 views
1

我有这个简单的类,我知道在内存泄漏方面没问题。objective-c对象内存管理

@interface location : NSObject { 
     NSString *name; 
     float lat; 
     float lon; 
     NSString *subtitle; 
    } 

    @property (nonatomic, retain) NSString *name; 
    @property (nonatomic, retain) NSString *subtitle; 
    @property (nonatomic, assign) float lat; 
    @property (nonatomic, assign) float lon; 


    @end 

    @implementation location 

    @synthesize name; 
    @synthesize lon; 
    @synthesize lat; 
    @synthesize subtitle; 

    -(void)dealloc{ 
     [name release]; 
     [subtitle release]; 
     [super dealloc]; 
    } 

    @end 

@property中有保留,所以我在dealloc方法中释放。现在,我的问题是:如果我在一个init方法或其他创建的方法中分配一个字符串,我应该做另一个版本吗?如果是这样,何时?

@implementation location 

@synthesize name; 
@synthesize lon; 
@synthesize lat; 
@synthesize subtitle; 

-(void) init{ 
     name = [[NSString alloc] init]; 
} 

-(void)dealloc{ 
    [name release]; // IS THIS CORRECT?! 
    [subtitle release]; 
    [super dealloc]; 
} 

@end 

回答

2

如果您正在使用self.符号,那么你应该release(如retain被自动调用,如果你使用synthesize)如果您使用用于创建新的对象alloc + init方式分配值。例如:

NSString *str = [[NSString alloc] init]; 
self.name = str; 
[str release]; 

如果您在使用分配符号self.价值和分配自动释放的对象,那么你不应该retainrelease。例如:

NSString *str = [NSString string]; 
self.name = str; 

如果不用self.前缀分配值,那么你不应该分配autorelease对象,不应该release,你只应该alloc + init对象。例如:

NSString *str = [[NSString alloc] init]; 
name = str; 

或者,如果你想assign自动释放对象,而self.前缀,那么你应该保留它。例如:

NSString *str = [NSString string]; 
name = [str retain]; 

dealloc方法,你应该release objects如果你没有做到这一点早。

+0

谢谢,第一个例子中解决我的问题。 –

0

基本上你不需要保留在这里,因为你没有重新任何东西。您的代码与分配了所有属性的代码相同。

除非您不调用self.name,否则不应用保留语义。

有一种代码风格可以消除这种混淆。保持属性名称和实例名称不同,并将实例名称分配给属性名称@synthesize。

像这样:

@interface location : NSObject { 
    NSString *name; 
} 

@property (nonatomic, retain) NSString *nameProp; 


@end 

@implementation location 

@synthesize nameProp = name; 
+0

通过这样做,您必须在哪里发布?你怎么能通过电话设置字符串? –

+0

如果你在位置类内部,只需做self.nameProp = nil;释放它,并self.nameProp = newObjet;用newObject替换它,这会自动释放分配给self.nameProp的前一个对象。如果您有一个名为locationObject的位置对象,则只需将self自定义到locationObject。 –