2010-05-29 113 views
3

好吧,所以我有一个方法,输入NSString作为输入,对此字符串的内容进行操作,并返回处理的字符串。所以声明:我应该返回一个NSMutableString返回NSString的方法

- (NSString *) processString: (NSString *) str; 

的问题:我应该回报,我作为我的“工作”缓冲的NSMutableString实例,或者我应该创建围绕可变一个新的NSString,并返回?

所以我应该这样做:

- (NSString *) processString: (NSString *) str 
{ 
    NSMutableString *work = [NSMutableString stringWithString: str]; 
    // process 'work' 
    return work; 
} 

或者这样:

- (NSString *) processString: (NSString *) str 
{ 
    NSMutableString *work = [NSMutableString stringWithString: str]; 
    // process 'work' 
    return [NSString stringWithString: work]; // or [work stringValue]? 
} 

第二个让我返回字符串的另一个副本,除非NSString确实喜欢副本上聪明事-修改。但是,第一个是在理论上,返回调用者可以稍后去修改的东西。我不在乎他们是否这样做,因为弦是他们的。但是,有没有正确的理由偏好后者的形式?而且,是stringWithString还是stringValue优于其他?

回答

6

完全取决于你需要如何防守。

您的代码的客户端可以测试可变性没有合理的方法。因此,客户端可以从NSString转换为NSMutableString并且突然实现字符串的无编译器警告可变性的合理方式。

所以,只要你相信你的客户,你也可以返回可变字符串(作为NSString)。即使客户端做了一些愚蠢的事情,并且改变了它,编译器的警告也会被诅咒,没有任何事情会发生。

它在哪里确实问题是当您返回某些不应该在外部进行变异的对象的可变后备存储区时。在这种情况下,客户端可能会忽略编译器警告和/或强制转换为可变类型,并且完全禁止您的对象。

或者,更为巧妙的是,客户端可能会获取对所谓的不可变返回类型的引用,并保持它足够长的时间,以便稍后发生变化,从而使其引用处于令人惊讶的状态。

最佳实践:计算并返回瞬态值时,可变性无关紧要。在返回一个内部可变存储的引用时,最好创建一个不可变的副本。