目标C中的内存管理?

时间:2011-08-04 10:53:40

标签: iphone memory-management

我有两个属性NSString,这两个属性我已经合成并且是只读的,所以我不能使用属性方法self。但我尽管两个传递的字符串都被保留了。所以,我添加了retain以保留属性。但我觉得,因为传递的对象增加了它们的保留计数,所以我会在这里泄漏。但是我的属性会保留这些字符串而不发送消息保留。

-(void)setValue:(NSString *)passedString1 second:(NSString *)passedString2{
     myString = [passedString1 retain];
     hisString = [passedString2 retain];
}

假设我将数组(变量)的属性声明为NSArray,并以此方式传递NSDictionary作为参数;

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"text", @"This is some text", nil];
[self setValueForArray:dict];

-(void)setValueForArray:(NSDictionary*)passedDict{
 NSArray *someArray = [NSArray arrayWithObject:passedDict];
 if(array!=someArray){
 [array release];
 array = someArray; //I dont think I should retain this property here since it is retained by someArray
 }
}

这种方法对于NSDictionary和NSArray类型是否正确。

3 个答案:

答案 0 :(得分:2)

对字符串使用copy并释放上一个对象:

-(void)setValue:(NSString *)passedString1 second:(NSString *)passedString2
{
     if (myString != passedString1)
     {
         [myString release]; 
         myString = [passedString1 copy];
     }

     if (hisString != passedString2)
     {
         [hisString release];
         hisString = [passedString2 copy];
     }
}

如果您需要release作为参数传入的字符串,请在调用setValue:

后在调用方法中执行此操作

答案 1 :(得分:1)

是的,如果你这样做,你的属性(更确切地说,对应于属性的实例变量)将保留传递的字符串。但是,您还必须确保在分配新值时释放以前的值。如,

- (void)setValue:(NSString*)passedString1 second:(NSString*)passedString2 {
    if (passedString1 != myString) {
        [myString release];
        myString = [passedString1 retain];
    }
    if (passedString2 != hisString) {
        [hisString release];
        hisString = [passedString2 retain];
    }
}

另外,请确保在myString方法中发布hisStringdealloc

答案 2 :(得分:1)

如果您希望保留任何属性,建议将该属性声明为retain并使用self。上面的代码容易泄漏内存,因为你在一个方法中保留了某些东西,并且可能在其他地方发布它们。这将导致很多麻烦,因为这两种方法彼此相关,而不是基于您的应用程序逻辑。 (可怕!!你以后在阅读代码时必须记住它。或者如果你想让其他人看你的代码那就把它记录下来......)

在我希望保留一些变量并且仍然不想在标题中使用retain属性的情况下,我创建了一个扩展并覆盖该属性然后使用self。

MyClass.h

@interface MyClass : NSObject
{
    SomeClass *someObject; //Example
    ...
}
@property (nonatomic) SomeClass *someObject;
...
@end

MyClass.m

@interface MyClass () //Category
@property (nonatomic, retain) SomeClass *someObject;
@end

@implementation MyClass
...
// Use self.someObject and the object will be retained.
// Release that object in dealloc.
@end

编辑:NSString与你的情况一样。只需将retain替换为copy,因为它推荐用于NSString。