Определение NSMutableString?

Используя блоки для ограничения объема хорошая техника в моей книге.

, Но так как Вы используете маркировку, чтобы сделать работу комментария, почему не только используют фактический комментарий вместо этого? Это удалило бы беспорядок о не имеющей ссылки маркировке.

8
задан Laurent Etiemble 24 January 2010 в 17:13
поделиться

6 ответов

 NSMutableString * newPath = [NSMutableString stringWithCapacity: 42];

ИЛИ

 NSMutableString * newPath = [[NSMutableString alloc] init];

Is there any particular reason why I should use one or the other, on the face of it it seems easier to use the first?

Yes. Always autorelease immediately unless you have a specific reason not to.

The first reason is that it's very easy to forget to write the release message. If you autorelease the object in the very same statement where you create it (as in [[[… alloc] init] autorelease]), it's much more difficult to forget it and much more obvious when you do. The convenience factory methods (such as stringWithCapacity:) autorelease the object for you, so just as when you autorelease it yourself, you don't have to worry about releasing it later.

Second, even if you do remember to write the separate release message, it's easy to not hit it. Two ways are early returns:

NSString *str = [[NSString alloc] initWithString:@"foo"];

BOOL success = [str writeToFile:path atomically:NO];
if (!success)
    return;

[str release];

and thrown or propagated exceptions:

NSString *str = [[NSString alloc] initWithString:@"foo"];

//Throws NSRangeException if str is not in the array or is only in the array as the last object
NSString *otherStr = [myArray objectAtIndex:[myArray indexOfObject:str] + 1];

[str release];

The “specific reason not to” is generally that you have a tight loop that creates a lot of objects, in which case you may want to manually manage as many of the objects in the loop as you can, in order to keep your object count down. However, only do this if you have evidence that this is your problem (be it hard numbers from Shark, hard numbers from Instruments, or your system going into paging hell whenever that loop runs long enough).

Other, possibly better, solutions include splitting the loop into two nested loops (the outer one to create and drain an autorelease pool for the inner loop) and switching to NSOperation. (However, make sure you set a limit on how many operations the queue runs at a time—otherwise, you may make it even easier to go into paging hell.)

Also is the first better as it gives the compiler a sense of size?

It is better, but not for that reason.

To the compiler, it's just another class message. The compiler does not know or care what it does; for all it knows and cares, stringWithCapacity: is the message to play a song to the user.

It does give NSMutableString a size hint—the class will know how much character storage it may want to initially allocate. Whatever benefit you get from this is probably small (at least on the Mac), but if you have the information handy, why not use it? Conversely, I wouldn't go out of my way to compute it.

I see a lot a declarations written on two lines (i.e.)

NSMutableString *newPath;
newPath = [NSMutableString stringWithCapacity: 42];

Лично я предпочитаю однострочный, это просто еще один пример личного стиля?

Да. Однако есть определенный риск, если оставить переменную неинициализированной. Обязательно включите настройку сборки «Запуск статического анализатора», если вы решите сделать это привычкой.

16
ответ дан 5 December 2019 в 06:54
поделиться

Первый не обязательно для компилятора, а скорее предложение для строки о том, как можно оптимизировать хранение своих данных. Это наиболее полезно для NSDictionary / NSArray / NSSet, которые имеют возможность внутренне изменять свои реализации в зависимости от размера их набора данных .

Кроме этого, вы правы: единственная разница это вопрос собственности. Я почти никогда не использую методы WithCapacity , а просто использую [NSMutableString string] или [NSMutableArray array] , но ИМО, это действительно вопрос стиля и вы ничего не получите и не потеряете, если будете использовать одно вместо другого.

4
ответ дан 5 December 2019 в 06:54
поделиться

The first one is an autoreleased string. This will be released by the system at an appropriate point. It is added to the autorelease pool and memory will be handled by the system. Once it is out of scope, you cannot garuntee that it will be valid. This type is useful if it only has scope within your method, and also for returning values from methods.

The second is retained, so will have a reference count of 1 and is not added to the autorelease pool. You are responsible for releasing it and freeing up the memory. Use this method if you want to control the scope of the object. Used for member variables etc.

I believe the 2 line initialisation is just style, but I would not use the 2 line variation as you are defining the variable without assinging a value to it, even though you are on the next line. I guess this kind of mirrors member variable declaration/initialisation, but I dont personally like it much.

2
ответ дан 5 December 2019 в 06:54
поделиться

You're correct on all your points!

I'm not sure how big a difference the size/capacity hint makes, but more information should certainly allow the run-time make better decisions.

Why use one style over the other? Well, when are autoreleased objects released? There are two non-obvious reasons why it might matter. First, when a method uses a lot of memory that you can release immediately. (You could also use a local autorelease pool I guess.) Secondly, I find that using autorelease can hide memory leaks and make debugging some code more difficult. Your mileage may vary depending on the age and quality of the code.

When I first started developing iPhone apps I used autoreleased objects all the time. It was convenient because I didn't fully understand how it all worked and it usually did the right thing. These days I tend to err on the side of manually deallocating memory. It really isn't that hard when you actually understand how the reference counting works and forces the issue immediately when you don't.

1
ответ дан 5 December 2019 в 06:54
поделиться

If you're pretty sure how long a string you'll need, go ahead and use the -initWithCapacity: method. When you exceed a string's storage, it gets reallocated and copied, which isn't a cheap operation.

0
ответ дан 5 December 2019 в 06:54
поделиться

Вы задаете правильные вопросы. Это действительно зависит от того, что вы делаете, но для обычных приложений для iPhone я бы сказал, просто используйте первое. Это будет автоматически очищено для вас, когда счетчик ссылок достигнет 0, и вам не нужно об этом беспокоиться.

Используйте второй, когда у вас действительно есть веская причина самостоятельно управлять памятью строки. Например, вы хотите быть уверенным в том, когда строка должна быть очищена, или вы ожидаете, что объем памяти будет минимальным в определенное время.

Я бы сказал, как общее правило, используйте второй, когда у вас есть веская причина для этого. итак.

1
ответ дан 5 December 2019 в 06:54
поделиться