2010-11-19 2 views
2

Я читал об autoreleasepool, но есть точка, которая немного неясна для меня. У меня есть некоторые функции, использующие потоки, которые требуют отдельного управления памятью, используя autoreleasepool.iPhone Autoreleasepool и распределения

В следующем примере правильно

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 

    NSString *myString = @"Hello"; 

    [pool release]; 
} 

Правильно ли это?

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 

    NSString *myString = [[NSString alloc] initWithString:@"Hello"]; 

    [pool release]; 
} 

или этот?

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 

    NSString *myString = [[NSString alloc] initWithString:@"Hello"]; 

    [myString release]; 
    [pool release]; 
} 

Мой вопрос собственности объектов, созданных в рамках этого autorelease бассейна нужно, будут опубликованы специально или являются позаботилась о том, когда autorelasepool будет выпущена?

Teo

ответ

1

Пульт автореферата обрабатывает автореализованные объекты. Если у вас есть объект (через alloc или copy или сохранить), вы должны его освободить. Поэтому ваш второй пример неверен. Поскольку вы выделили строку, вы ее обладаете, и вы должны ее освободить.

Пул авторефератов создан для основной темы. (Вы можете посмотреть основную функцию, если хотите). Каждому потоку нужен собственный пул автозапуска для управления автореализованными объектами. Вот почему, если вы создаете другой поток, вы должны создать пул автозапуска для этого потока. Даже если вы не создаете автореализованный объект в потоке, вы должны создать его, поскольку вызовы библиотеки в этом потоке могут создавать объекты с автореализацией.Даже если вы уверены, что никакие вызовы библиотек не создают автореализованные объекты, вам также следует создать их, поскольку это лучшая практика, особенно если вы работаете над большим проектом, который разрабатывается и поддерживается несколькими людьми.

0

Вам только нужно, чтобы создать свой собственный autorelease бассейн, когда вы создаете кучу autoreleased объектов, которые вы хотите собрать мусор сразу. Тем не менее, вы правы в том, что не хотите ссылаться на какие-либо «автореализованные» объекты, созданные вами после выпуска пула. Автореализованные объекты (которые вы не сохраняете) уничтожаются при пуске пула.

Поскольку ни один из объектов в вашем примере не автореализован, создание собственного пула авторесурсов по существу является не-операционным.

+0

На самом деле он говорит о нитке. Поэтому необходим автореферат. – taskinoor

+0

Зачем, если он не создает какие-либо объекты с автореализацией? – zoul

+0

@zoul, пожалуйста, проверьте последнюю часть моего ответа. Хотя вы, возможно, не согласитесь, я предпочту следовать лучшим практикам. – taskinoor

0

Ни один из ваших примеров не нуждается в пуле автономии. Autorelease бассейны только заботиться о autoreleased объектов:

NSArray *foo = [NSArray array]; 
NSObject *bar = [[[NSObject alloc] init] autorelease]; 

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

Это где вам нужно будет бассейн:

- (void) someMethodThatRunsOnAThread { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSString *foo = [@"foo" uppercaseString]; 
    [pool drain]; 
} 

Здесь foo строка будет течь, если бассейн не был там. Заметьте, что я звоню drain вместо release на пул - на iOS нет никакой разницы, но в мусорных средах они отличаются друг от друга, поэтому, вероятно, лучше привыкнуть к правильному.

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

+0

На самом деле он говорит о нитке. Я думаю, что методы примера работают в отдельном потоке. – taskinoor

+0

Вам не нужен пул автозапуска в потоке, если вы не создаете никаких объектов с автореализацией. – zoul

+0

, пожалуйста, проверьте последнюю часть моего ответа. Хотя вы, возможно, не согласитесь, я предпочту следовать лучшим практикам. – taskinoor

0

Подумайте, что это должно быть что-то вроде этого:

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 


    NSString *myString = [[[NSString alloc] initWithString:@"Hello"] autorelease]; 

    // or create string like this (automatically autoreleased) 
    NSString *myString = [NSString stringWithString:@"Hello"]; 

    [pool release]; 
} 

Вы должны отправить сообщение autorelease, к объектам внутри autorelease бассейна. Они будут выпущены, когда сообщение о выпуске будет отправлено в пул.

+0

Не перевыпускаете ли вы пул, отправляя как '-drain', так и' -release'? – zoul

+0

упс ... да ... :) – marko

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