简体   繁体   English

什么时候不分配和初始化NSString

[英]When not to alloc and init an NSString

Whenever I need to create a new NSString variable I always alloc and init it. 每当我需要创建一个新的NSString变量时,我总是分配并初始化它。 It seems that there are times when you don't want to do this. 似乎有时候你不想这样做。 How do you know when to alloc and init an NSString and when not to? 你怎么知道何时分配和初始化NSString以及什么时候不?

Whenever I need to create a new NSString variable I always alloc and init it. 每当我需要创建一个新的NSString变量时,我总是分配并初始化它。

No, that doesn't make sense. 不,这没有意义。

The variable exists from the moment the program encounters the point where you declare it: 变量从程序遇到您声明它的那一刻起就存在:

NSString *myString;

This variable is not an NSString. 此变量不是NSString。 It is storage for a pointer to an NSString. 它是指向NSString的指针的存储。 That's what the * indicates: That this variable holds a pointer. 这就是*表示的内容:该变量包含指针。

The NSString object exists only from the moment you create one: NSString 对象仅在您创建一个对象时存在:

[[NSString alloc] init];

and the pointer to that object is only in the variable from the moment you assign it there: 并且指向该对象的指针仅在您在其中分配时的变量中:

myString = [[NSString alloc] init];
//Or, initializing the variable in its declaration:
NSString *myString = [[NSString alloc] init];

Thus, if you're going to get a string object from somewhere else (eg, substringWithRange: ), you can skip creating a new, empty one, because you're just going to replace the pointer to the empty string with the pointer to the other one. 因此,如果你要从其他地方获取一个字符串对象(例如, substringWithRange: ,你可以跳过创建一个新的空字符串,因为你只是要用指针替换指向空字符串的指针。另一个。

Sometimes you do want to create an empty string; 有时您确实想要创建一个空字符串; for example, if you're going to obtain a bunch of strings one at a time (eg, from an NSScanner) and want to concatenate some or all of them into one big string, you can create an empty mutable string (using alloc and init ) and send it appendString: messages to do the concatenations. 例如,如果你要一次一个地获取一串字符串(例如,来自NSScanner)并想要将它们中的一些或全部连接成一个大字符串,你可以创建一个空的可变字符串(使用allocinit )并发送appendString:消息来进行连接。

You also need to release any object you create by alloc . 您还需要release您通过alloc创建的任何对象。 This is one of the rules in the Memory Management Programming Guide . 这是“ 内存管理编程指南”中的规则之一。

If you want to initialise it to a known value, there is little point in using alloc , you can just use a string literal: 如果要将其初始化为已知值,使用alloc几乎没有意义,可以使用字符串文字:

NSString* myStr = @"Some value";

If you want to initialise it with a format or whatever, but don't need it to stick around beyond the current autorelease pool lifetime, it's a bit neater to use the class convenience methods: 如果你想用格式或其他东西初始化它,但不需要它超出当前的自动释放池生命周期,使用类方便方法有点整洁:

NSString* myTempStr = [NSString stringWithFormat:@"%d", myIntVar];

If you need its lifetime to go beyond that, either alloc / init or else add a retain to the previous call. 如果你需要它的生命周期超过它,可以使用alloc / init或者为前一个调用添加一个retain I tend to slightly prefer the latter, but the two are pretty much equivalent. 我倾向于略微偏爱后者,但两者几乎相当。 Either way you will need a balancing release later. 无论哪种方式,您都需要稍后平衡release

Note that, since NSString is not mutable, this sort of thing is not only unnecessary but actively wrong : 请注意,由于NSString不可变,因此这种事情不仅是不必要的,而且是主动错误的

// don't do this!
NSString* myStr = [[NSString alloc] initWithString:@""];
myStr = someOtherStr;

since it leaks the initial placeholder value. 因为它泄漏了初始占位符值。

It seems that there are times when you don't want to do this. 似乎有时候你不想这样做。

I can't think of any time when I would want to alloc/init a NSString. 我想不出任何时候,我想分配/初始化一个NSString的。 Since NSStringgs are immutable, you pretty much always create new strings by one of: 由于NSStringgs是不可变的,因此您几乎总是通过以下方法之一创建新字符串:

  • convenience class method eg 便利类方法,例如

     NSString* foo = [NSString stringWithFormat:...]; 
  • literal 文字

     NSString* foo = @"literal"; 
  • NSString instance method NSString实例方法

     NSString* foo = [bar uppercaseString]; 
  • copy from mutable string 从可变字符串复制

     NSString* foo = [mutableBar copy]; // foo needs to be released or autoreleased in this case 

I'm guessing that you are referring to using StringWithString or similar instead of initWithString? 我猜你指的是使用StringWithString或类似的而不是initWithString? StringWithString alloc and inits for you under the hood and then returns an autoreleased string. StringWithString在你的引擎盖下为你分配并返回一个自动释放的字符串。

If you don't need to do any string manipulation other than to have the string, you can use NSString *str = @"string"; 如果除了拥有字符串之外不需要进行任何字符串操作,可以使用NSString *str = @"string";

In general with iOS, the tighter you manage your memory the better. 一般情况下,使用iOS,您管理内存越严格越好。 This means that if you don't need to return a string from a method, you should alloc init and then release it. 这意味着如果您不需要从方法返回字符串,则应该分配init然后释放它。

If you need to return a string, of course you'll need to return an autoreleased string. 如果你需要返回一个字符串,当然你需要返回一个自动释放的字符串。 I don't think its any more complicated than that. 我认为它没有那么复杂。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM