2

我想要一些帮助以更好地理解 Cocoa 中字符串的内存特性。我正在使用的应用程序使用一个视图控制器和 n 个工具对象。视图控制器在程序的生命周期中存在,但工具对象被分配和释放。

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

我想知道将传入值存储到 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;
    }

 }

建议表示赞赏。

4

1 回答 1

1

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

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

因此,在您的情况下,我建议使用这样的二传手:

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

这样你就做得很好,你不应该关心 setter 参数的保留计数是多少。如果它是一个具有未知保留计数的字符串文字,则该对象甚至不会响应释放消息,因此它将为所有程序保持活动状态(不像它看起来很有效,因为它避免了创建对象的开销在运行时)。如果你复制一个不可变的对象(除非它像缓存的NSNumber或字符串文字),代码只是做一个简单的赋值,并且保留计数会增加。

因此,如果您只是遵循“我保留(或复制)我需要使用的内容,我释放我不再需要使用的内容”的规则,那么您做得很好,您不必担心会发生什么特殊情况,例如字符串文字。

于 2013-06-19T16:15:51.810 回答