2013-06-19 54 views
2

我希望能更好地理解Cocoa中字符串的内存特性。 我正在使用的应用程序使用一个视图控制器和n个工具对象。视图控制器在程序的整个生命周期中生存,但工具对象被分配和释放。当在常量字符串和非常量字符串之间交替时,NSString的最佳分配

假设我有一个字符串toolName_并在我的实现中配置了传入的工具对象:如果对象没有工具名称,我想将toolName_ string设置为@“not set”。如果该工具有一个名称,我想将该字符串设置为该工具的名称。

我想知道存储传入的值到toolName_因为有时这将是一个分配的对象,有时这将是一个常量字符串的正确方法。

-(BOOL)setToolObject: ToolObject: obj{ 

    ToolObject someObj = nil; 
    someObj = [[ToolObject alloc]initWithObject obj]; 

    if(someObj != nil){ 

     if(! [someObj.toolName isEqualToString: @""]){ 

      self->toolName_ = Which method should I use given the above question? 
      The last instance may have been a constant string but may not have. 
      [self->toolName_ release] (can I send a release message to a constant 
      string without causing a problem?) 
      self->toolName = [[NSString alloc]initWithString:someObj.toolName]; 

       OR 

      self->tool name = [NSString stringWithString: someObj.toolName]; 
      This method is self releasing but I don't own it and I'm still not sure 
      what happens to the constant string if it existed. I think I read it's 
      not recommended to use this on member vars. 

     }else{ 

      self->toolName_ = @"not set"; 
     } 

     return YES;   

    }else{ 

     return NO; 
    } 

} 

建议感激。

+1

通常,'self>不用于访问Objective-C中的ivars。同样,具有返回值的setter也非常不典型。你通常希望限制setter/getter到可以用'@ property'表示的东西。 – bbum

回答

1

我强烈建议(可能)使用ARC,如果你不能使用它(或者你只是想了解内存管理是如何工作的?),对不送保留和从类的外部释放邮件。相反,您应该在访问器中执行此操作。

所以你应该创建一个保留或复制属性(通常使用不可变字符串比使用复制更可取,因为它们可能被分配给可变字符串,因此使得假设你正在使用不可变 - 因此线程安全 - 属性)。

所以你的情况,我建议这样的一个二传手:

- (void) setToolName: (NSString*) toolName 
{ 
    if(_toolName== toolName) 
     return; 
    [_toolName release]; 
    _toolName= [toolName copy]; 
} 

这样,你这样做很好,你不应该关心什么是二传手参数的保留计数。如果它是一个具有未知保留计数的字符串字面值,则该对象甚至不响应释放消息,因此它将对所有程序保持活动状态(不像它看起来是高效的,因为它避免了创建对象的开销在运行时)。如果复制不可变对象(除非它像一个缓存的NSNumber,或文字字符串),代码只是做了简单的分配和保持数被提高。

所以,如果你只是遵循的原则:“我保留(或复制)我需要什么用,我释放了什么,我不需要再使用”,你这样做很好,你不应该担心关于特殊情况下会发生什么情况,比如字符串文字。

+1

不过,如果你打算使用一个setter喜欢的那一个,你是更好的使用'@财产(副本)的NSString *工具名关;'和让编译器合成的setter/getter和自动伊娃。 – bbum

+0

是的,当然这只是为了说明这个概念。 –