是alloc + initWithString:与copy相同吗?

时间:2011-12-05 13:32:06

标签: cocoa nsstring

基本上,问题是 - 以下内容基本相同吗?

NSString *value1 = ...;
NSString *value2 = [[NSString alloc] initWithString:value1];

NSString *value1 = ...;
NSString *value2 = [value1 copy];

2 个答案:

答案 0 :(得分:5)

从概念上讲,是的。但是,有一个区别:alloc总是创建一个新字符串,而copy可能会返回相同的字符串。

特别是,不可变对象(如不可变字符串)可能通过返回自身而不是创建并返回副本来响应copy。 (毕竟,如果你不能改变关于原文的任何内容,为什么你真的需要一个副本?)可变字符串将通过创建和返回副本来响应它,正如你所期望的那样。

initWithString:位于中间:它可以释放接收器并返回您给它的字符串,类似于copy可能返回接收器的方式。但是,如果发生这种情况,则意味着您浪费了使用alloc创建的字符串的浪费。使用copy,您可能根本不需要创建任何其他对象。

关于使用allocinitWithString:的唯一原因是,如果您拥有自己的NSString子类,并希望从现有字符串中创建它的实例。 copy不会使用您想要的子类。由于在Cocoa中实际上从不保证NSString的子类化,因此使用initWithString:(或stringWithString:)也是如此。

所以底线是,只需使用copy(或mutableCopy)。它更短,更清楚你的意图,而且可以更快。

答案 1 :(得分:0)

与普通对象相比,非可变字符串的处理有点特殊,所以在这种情况下,是的,这两个操作是相同的。

即便:

NSString *str1 = @"string";
NSString *str2 = [str1 copy];
NSString *str3 = [[NSString alloc] initWithString: str1];

NSLog(@"str1: %p, str2: %p, str3: %p", str1, str2, str3);

这给了我以下输出:

str1: 0x108a960b0, str2: 0x108a960b0, str3: 0x108a960b0

由于指针地址相同,我们讨论的是同一个对象。