2012-05-01 3 views
1

Я новичок в Objective-C, и я не уверен, использую ли я NSAutoreleasePool правильный путь.Это правильный способ использования NSAutoreleasePool?

  1. Если я хочу использовать autorelease только один раз я использую:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSString *newText = [NSString stringWithFormat:@"%d", prograssAsInt]; 
    sliderLabel.text = newText; 
    [pool release]; //newText will be released 
    
  2. Если я хочу использовать autorelease несколько раз я использую:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSString *newText = [NSString stringWithFormat:@"%d", prograssAsInt]; 
    sliderLabel.text = newText; 
    [pool drain]; //newText will be released 
    newText = [NSString stringWithFormat:@"%d", prograssAsInt]; 
    sliderLabel.text = newText; 
    [pool drain]; //newText will be released 
    newText = [NSString stringWithFormat:@"%d", prograssAsInt]; 
    sliderLabel.text = newText; 
    [pool release]; //newText will be released 
    

Это ОК? Есть ли утечки памяти?

ответ

3

(2) не в порядке. -drain и -release эквивалентны (в среде пересчета), а после -drain пул авторасчетов освобождается. Таким образом, вы удвоите выпуск объекта пула автозапуска и скомпрометируете программу.

Даже до ARC, если вы работаете в очень ограниченном бюджете памяти, нетипично создать NSAutoreleasePool, кроме шаблона main(). Объекты -autorelease d в пул будут выпущены после каждого тика NSRunLoop в любом случае. Не будет утечки памяти, если вы строго соблюдаете правила передачи прав собственности (см. Understanding reference counting with Cocoa and Objective-C).

И с ARC включена вам даже не нужно заботиться об этом - компилятор вставит -retain и -release в нужном месте для вас.


Кроме того, если sliderLabel.text отмечен как @property(retain) (или (strong)), а затем отпуская autorelease бассейн в (1) не будет выпускать newText потому, что объект имеет новый владелец в настоящее время.

3

Я бы сказал, что звонки на [pool drain] не нужны. Я никогда не видел, чтобы они использовались на практике. Я полагаю, что если вы выделяете огромное количество памяти внутри пула автозапуска, это может быть необходимо. Но в типичном случае я бы не подумал.

Вы хотите начать использовать следующую конструкцию, кстати, для autorelease бассейнов:

@autoreleasepool { 
    ... your code ... 
} 

Это, по-видимому, гораздо более эффективным, чем «старый» способ (так, как вы делаете это). Функционально это одно и то же, но внутренне оно работает намного лучше. В недавних заметках о выпуске Xcode/iOS было что-то в этом роде.

3

Извините, что это RTFM. После того, как вызывается -drain, пул освобождает себя, поэтому он недействителен.

И, в настоящее время, в Objective-C с LLVM компилятор Apple, есть язык дополнение называется @autoreleasepool, который работает как с ARC и не-ARC кода, который можно использовать в качестве таковых:

@autoreleasepool { 
    // code that will automatically have any -autoreleased variables cleaned up. 
} 
+0

Я думаю, что грубость необоснованна. Хотя это задокументировано, это очень противоречиво, до такой степени, что я слышал от опытных программистов Cocoa, которые действительно читали документацию и не верили, что это означает то, что она сказала. Я не думаю, что это необоснованный вопрос для кого-то нового в рамках. – Chuck

3

Обычно, если вы находитесь в основном потоке, и вы не используете огромный цикл ресурсоемких программ, вам больше не нужно создавать собственные пулы автоопределений. Просто используйте созданный по умолчанию файл по умолчанию.

Вам нужно только сделать свой собственный, если вы многопоточность или если вы занимаетесь интенсивным долговременным циклом памяти (который вы, вероятно, не должны делать в основном потоке).

Смежные вопросы