我想比较以下简单的作业:
...
@property(nonatomic,retain) UITextField *textField;
...
self.textField.text = @"some string";
self.textField.text = [NSString stringWithString:@"some string"];
self.textField.text = [NSString stringWithFormat:@"some string"];
其中textField
为UITextField
,text
属性为NSString
。当然所有这些都有效。我知道使用参数时最后两个的区别。但是让我们说我们只对这种用法感兴趣。
问题:
stringWithString:
?答案 0 :(得分:12)
总是尽量做自然感觉。如果你要分配一个常量字符串,那么就这样做,即第一个选项。 @"..."
字符串是非常有效的常量,不需要进行内存管理,因此如果有意义则使用它们。
NSLog(@"%p", @"XX");
NSLog(@"%p", @"XX");
NSLog(@"%p", @"XX");
结果:
0xa2424
0xa2424
0xa2424
即。它们在记忆中都是相同的对象。
NSLog(@"%p", [NSString stringWithString:@"XX"]);
NSLog(@"%p", @"XX");
NSLog(@"%p", [NSString stringWithString:@"XX"]);
同样导致:
0xa2424
0xa2424
0xa2424
正如您所看到的,两个对象之间没有区别,因此使用-stringWithString:
只是一个额外的消息要发送。话虽如此,开销通常不足以产生差异,所以无论如何都不应该是一个大问题。我个人会选择方法一,因为没有使用方法二的好处,它只是额外的代码。
然而,
NSLog(@"%p", [NSString stringWithFormat:@"XX"]);
NSLog(@"%p", [NSString stringWithFormat:@"XX"]);
NSLog(@"%p", [NSString stringWithFormat:@"XX"]);
结果:
0x7f86730
0xf8479b0
0x8a4cdb0
正如您所看到的,每次都会创建一个新字符串,因为您提供的sting只是一个格式字符串,用于处理以下替换变量,因为除非您需要,否则无法避免stringWithFormat:
。
(显然所有地址都是例子......)
答案 1 :(得分:6)
为了做这种任务,我为什么不总是使用第一个?
对于那种作业,你总是使用第一种,而不是最后两种。
为什么我应该使用stringWithString:如果没有?
你的直觉是正确的。在大多数情况下-stringWithString:
具有可疑价值。它主要用于NSMutableString
,它是NSString
的子类。
例如:
NSMutableString* myString = [NSMutableString stringWithString:@"Foo"];
[myString appendString:@"Bar"];
如果要将NSMutableString转换为NSString,或者确保您正在处理NSString实例,也可以使用它。例如:
- (void):setMyString:(NSString*)newString
{
[_myString release];
_myString = [[NSString stringWithString:newString] retain];
}
这是确保_myString
ivar指向NSString实例而不是NSMutableString实例的一种方法。并且仅在必要时复制newString
实例。
但是,在这种情况下,大多数开发人员只会使用_myString = [newString copy];
。
答案 2 :(得分:4)
为了做这种任务,我为什么不总是使用第一个?
总是在您描述的情况下使用第一个。第二种和第三种情况可能会复制常量字符串,但UITextField的text
属性被指定为复制提供的字符串。制作常量字符串的副本是没有意义的,因此UITextField的-setText:
可以复制该副本。
比较最后两个,编译有什么不同 - 和/或这两个运行时?为什么我应该使用stringWithString:at 所有,如果没有?
我的理解是-stringWithFormat:
将始终创建一个新字符串,而-stringWithString:
可能不会(可能不会)创建一个常量字符串。 hypercrypt上面的结果在这方面非常有说服力;如果你想探索更多,你可以尝试使用可变字符串进行相同的测试。
答案 3 :(得分:-2)
如果您使用第一个或第二个字符串,我认为这不重要。 我通常会使用第二个。
在第二个和第三个的情况下,如果你想在字符串中包含另一个变量,那么你使用stringWithFormat。否则,请使用stringWithString。
int number = 5;
NSString *str = [NSString stringWithFormat:@"Number is: %i", number];
// Str is "Number is: 5"
您将使用stringWithString的情况:
NSString *myName = [NSString stringWithString:@"FN LN"];
// myName is "FN LN"
如果没有其他变量要包含在字符串中,您将使用后者。
此外,这个问题已在其他地方无数次回答过。