使用[NSString stringWithString:@“some string”]与@“some string”的优点和缺点

时间:2011-11-25 23:35:05

标签: objective-c ios cocoa-touch cocoa nsstring

我想比较以下简单的作业:

...
@property(nonatomic,retain) UITextField *textField;
...

self.textField.text = @"some string";
self.textField.text = [NSString stringWithString:@"some string"];
self.textField.text = [NSString stringWithFormat:@"some string"];

其中textFieldUITextFieldtext属性为NSString。当然所有这些都有效。我知道使用参数时最后两个的区别。但是让我们说我们只对这种用法感兴趣。

问题:

  1. 为了做这种任务,我为什么不总是使用第一个?
  2. 比较最后两个,这两个的编译和/或运行时间有什么不同吗?如果没有,我为什么要使用stringWithString:

4 个答案:

答案 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"

如果没有其他变量要包含在字符串中,您将使用后者。

此外,这个问题已在其他地方无数次回答过。