这两种NSString方法之间的区别

时间:2022-05-26 16:39:59

So I just got asked this at an interview today and after some googling am still unable to figure out the answer (in fact I couldn't even find any code at all which used the [NSString string] method).

所以我今天在接受采访时被问到这个问题,经过一些谷歌搜索仍然无法找到答案(事实上我甚至找不到任何使用[NSString string]方法的代码)。

What is the difference between

有什么区别

  1. NSString *someString = [NSString string];
  2. NSString * someString = [NSString string];

  3. NSString *someString = [[NSString alloc] init];
  4. NSString * someString = [[NSString alloc] init];

Now my initial thoughts were that [NSString string] would return an object which would be autoreleased whereas using alloc and init would return an object which has been retained. However it seems that this answer was incorrect.

现在我最初的想法是[NSString string]将返回一个自动释放的对象,而使用alloc和init将返回一个已保留的对象。然而,似乎这个答案是不正确的。

I've looked at the NSString class reference in the apple docs but all it says is

我查看了苹果文档中的NSString类引用,但它说的是

Returns an empty string.

+ (id)string 

Return Value
An empty string.

Could somebody explain to me exactly what the difference between these two are?

有人可以向我解释这两者之间究竟有什么区别吗?

5 个解决方案

#1


4  

Now my initial thoughts were that [NSString string] would return an object which would be autoreleased

现在我最初的想法是[NSString string]会返回一个自动释放的对象

Technically, it’s a placeholder string that is constant, i.e., it lives throughout the entire program execution, never being released. It’s not an autoreleased string. Conceptually, and this is what I’d focus as an interviewer, it’s a string (an empty string) that is not owned by the caller, hence the caller shouldn’t release it.

从技术上讲,它是一个恒定的占位符字符串,即它贯穿整个程序执行,永远不会被释放。它不是一个自动释放的字符串。从概念上讲,这就是我作为访问者所关注的内容,它是一个字符串(空字符串),不是调用者所拥有的,因此调用者不应该释放它。

whereas using alloc and init would return an object which has been retained

而使用alloc和init将返回一个已保留的对象

Technically, it’s a placeholder string that is constant, i.e., it lives throughout the entire program execution. In fact, it’s the same object as the one above, and it is not retained. Conceptually, and this is what I’d focus as an interviewer, it’s a string (an empty string) that is owned by the caller, hence the caller is responsible for releasing it when it’s not needed any longer.

从技术上讲,它是一个恒定的占位符字符串,即它贯穿整个程序执行。事实上,它与上面的对象相同,并没有保留。从概念上讲,这是我作为访问者所关注的内容,它是一个由调用者拥有的字符串(空字符串),因此调用者负责在不再需要时释放它。

#2


5  

Was that your response, and did you ask why your answer was incorrect? I ask because your assumption is mostly correct (at a higher level).

这是你的回答,你问为什么你的回答不正确?我问,因为你的假设大多是正确的(在更高的层次上)。

It's not exactly 'retained' when returned from alloc+init, it is an object you hold one reference to, and should balance with a release or autorelease. For the convenience constructor (+[NSString string]), you are returned an object which you hold zero references to, but one which you can expect to live until the current autorelease pool is popped unless you send it an explicit retain (assuming MRC or ARC, since it is tagged iOS).

当它从alloc + init返回时,它并不完全“保留”,它是一个对象,你持有一个引用,并且应该与release或autorelease平衡。对于方便构造函数(+ [NSString string]),将返回一个对象,该对象保持零引用,但是在弹出当前自动释放池之前,您可以使用该对象,除非您向其发送显式保留(假设为MRC或ARC,因为它被标记为iOS)。

At the lower level, you could make some guesses, but I wouldn't expect that question in many objc interviews (unless you told them you were mid or senior level). Basically, it is implementation defined, but both forms could return the same static, constant NSString (that may have been what the interviewer was looking for). To illustrate:

在较低级别,你可以做一些猜测,但我不会在许多对象访谈中期待这个问题(除非你告诉他们你是中级或高级)。基本上,它是实现定义的,但两种形式都可以返回相同的静态,常量NSString(这可能是面试官正在寻找的)。为了显示:

@implementation NSString

static NSString * const EmptyNSString = @"";

- (id)init
{
    self = [super init];
    [self release];
    return EmptyNSString;
}

+ (id)string
{
    return EmptyNSString;
}

...

Again, that's implementation defined, but an obvious optimization. As well, that optimization makes physically subclassing concrete immutable types (NSString) difficult for mutable variants (NSMutableString) in some cases.

再次,这是实现定义,但明显的优化。同样,在某些情况下,该优化使得物理子类化具体的不可变类型(NSString)难以用于可变变体(NSMutableString)。

#3


4  

The correct answer is that

正确的答案是

NSString *someString = [NSString string];

gives you an empty string that you do not own and that you must not release (according to the memory management rules)

给你一个你不拥有的空字符串,你不能释放(根据内存管理规则)

whereas

NSString *someString = [[NSString alloc] init];

gives you an empty string you do own and that you must release (according to the memory management rules).

给你一个你自己的空字符串,你必须释放(根据内存管理规则)。

Without poking into the implementation, you can't say anything else about those two strings. You can't say that they are autoreleased, because they might not be and you can't say what the retain count will be.

如果不进行实现,就不能对这两个字符串说任何其他内容。你不能说它们是自动释放的,因为它们可能不是,你不能说保留计数是什么。

In actual fact, you'll probably get (in both cases) the same pointer to a constant object of some NSString subclass, probably with a retain count of UINT_MAX which is used by the run time as a flag to disable normal retain release behaviour for constant strings. I haven't actually tried the above because nobody except the maintainers of the Objective-C SDK needs to care.

实际上,您可能会(在两种情况下)获得指向某个NSString子类的常量对象的相同指针,可能保留计数为UINT_MAX,运行时将其用作禁用正常保留释放行为的标志。常量字符串。我实际上没有尝试过上述内容,因为除了Objective-C SDK的维护者之外,没有人需要关心。

#4


0  

You don't often see

你不经常看到

NSString *someString = [NSString string]; 

because it's the same as

因为它是一样的

NSString *someString = @""; 

which is shorter. It's usually used to create an empty NSMutableString

这更短。它通常用于创建一个空的NSMutableString

NSMutableString* s = [NSMutableString string];

#5


0  

The only thing I can imagine is that:

我唯一能想到的是:

  1. Won't allocate memory since it is not made with alloc. It is a constant (an empty string) made by the system and doesn't need to be released.

    不会分配内存,因为它不是由alloc创建的。它是系统生成的常量(空字符串),不需要释放。

  2. You allocate the memory for the NSString yourself which means you have to keep track if the NSString still 'lives' or not when you are done with it, and thus need to release it.

    您自己为NSString分配内存,这意味着当您完成NSString时,您必须跟踪NSString是否仍然“存在”,因此需要释放它。

#1


4  

Now my initial thoughts were that [NSString string] would return an object which would be autoreleased

现在我最初的想法是[NSString string]会返回一个自动释放的对象

Technically, it’s a placeholder string that is constant, i.e., it lives throughout the entire program execution, never being released. It’s not an autoreleased string. Conceptually, and this is what I’d focus as an interviewer, it’s a string (an empty string) that is not owned by the caller, hence the caller shouldn’t release it.

从技术上讲,它是一个恒定的占位符字符串,即它贯穿整个程序执行,永远不会被释放。它不是一个自动释放的字符串。从概念上讲,这就是我作为访问者所关注的内容,它是一个字符串(空字符串),不是调用者所拥有的,因此调用者不应该释放它。

whereas using alloc and init would return an object which has been retained

而使用alloc和init将返回一个已保留的对象

Technically, it’s a placeholder string that is constant, i.e., it lives throughout the entire program execution. In fact, it’s the same object as the one above, and it is not retained. Conceptually, and this is what I’d focus as an interviewer, it’s a string (an empty string) that is owned by the caller, hence the caller is responsible for releasing it when it’s not needed any longer.

从技术上讲,它是一个恒定的占位符字符串,即它贯穿整个程序执行。事实上,它与上面的对象相同,并没有保留。从概念上讲,这是我作为访问者所关注的内容,它是一个由调用者拥有的字符串(空字符串),因此调用者负责在不再需要时释放它。

#2


5  

Was that your response, and did you ask why your answer was incorrect? I ask because your assumption is mostly correct (at a higher level).

这是你的回答,你问为什么你的回答不正确?我问,因为你的假设大多是正确的(在更高的层次上)。

It's not exactly 'retained' when returned from alloc+init, it is an object you hold one reference to, and should balance with a release or autorelease. For the convenience constructor (+[NSString string]), you are returned an object which you hold zero references to, but one which you can expect to live until the current autorelease pool is popped unless you send it an explicit retain (assuming MRC or ARC, since it is tagged iOS).

当它从alloc + init返回时,它并不完全“保留”,它是一个对象,你持有一个引用,并且应该与release或autorelease平衡。对于方便构造函数(+ [NSString string]),将返回一个对象,该对象保持零引用,但是在弹出当前自动释放池之前,您可以使用该对象,除非您向其发送显式保留(假设为MRC或ARC,因为它被标记为iOS)。

At the lower level, you could make some guesses, but I wouldn't expect that question in many objc interviews (unless you told them you were mid or senior level). Basically, it is implementation defined, but both forms could return the same static, constant NSString (that may have been what the interviewer was looking for). To illustrate:

在较低级别,你可以做一些猜测,但我不会在许多对象访谈中期待这个问题(除非你告诉他们你是中级或高级)。基本上,它是实现定义的,但两种形式都可以返回相同的静态,常量NSString(这可能是面试官正在寻找的)。为了显示:

@implementation NSString

static NSString * const EmptyNSString = @"";

- (id)init
{
    self = [super init];
    [self release];
    return EmptyNSString;
}

+ (id)string
{
    return EmptyNSString;
}

...

Again, that's implementation defined, but an obvious optimization. As well, that optimization makes physically subclassing concrete immutable types (NSString) difficult for mutable variants (NSMutableString) in some cases.

再次,这是实现定义,但明显的优化。同样,在某些情况下,该优化使得物理子类化具体的不可变类型(NSString)难以用于可变变体(NSMutableString)。

#3


4  

The correct answer is that

正确的答案是

NSString *someString = [NSString string];

gives you an empty string that you do not own and that you must not release (according to the memory management rules)

给你一个你不拥有的空字符串,你不能释放(根据内存管理规则)

whereas

NSString *someString = [[NSString alloc] init];

gives you an empty string you do own and that you must release (according to the memory management rules).

给你一个你自己的空字符串,你必须释放(根据内存管理规则)。

Without poking into the implementation, you can't say anything else about those two strings. You can't say that they are autoreleased, because they might not be and you can't say what the retain count will be.

如果不进行实现,就不能对这两个字符串说任何其他内容。你不能说它们是自动释放的,因为它们可能不是,你不能说保留计数是什么。

In actual fact, you'll probably get (in both cases) the same pointer to a constant object of some NSString subclass, probably with a retain count of UINT_MAX which is used by the run time as a flag to disable normal retain release behaviour for constant strings. I haven't actually tried the above because nobody except the maintainers of the Objective-C SDK needs to care.

实际上,您可能会(在两种情况下)获得指向某个NSString子类的常量对象的相同指针,可能保留计数为UINT_MAX,运行时将其用作禁用正常保留释放行为的标志。常量字符串。我实际上没有尝试过上述内容,因为除了Objective-C SDK的维护者之外,没有人需要关心。

#4


0  

You don't often see

你不经常看到

NSString *someString = [NSString string]; 

because it's the same as

因为它是一样的

NSString *someString = @""; 

which is shorter. It's usually used to create an empty NSMutableString

这更短。它通常用于创建一个空的NSMutableString

NSMutableString* s = [NSMutableString string];

#5


0  

The only thing I can imagine is that:

我唯一能想到的是:

  1. Won't allocate memory since it is not made with alloc. It is a constant (an empty string) made by the system and doesn't need to be released.

    不会分配内存,因为它不是由alloc创建的。它是系统生成的常量(空字符串),不需要释放。

  2. You allocate the memory for the NSString yourself which means you have to keep track if the NSString still 'lives' or not when you are done with it, and thus need to release it.

    您自己为NSString分配内存,这意味着当您完成NSString时,您必须跟踪NSString是否仍然“存在”,因此需要释放它。