Многопоточный и авто-релизный пул - PullRequest
5 голосов
/ 13 февраля 2011

Поскольку я осваиваю свои навыки работы с многопоточностью с помощью GCD, я столкнулся с некоторым вопросом. Предположим, у вас есть следующий метод:

    - (void)method {
    NSString *string= [NSString string]; //will be autoreleased

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    //very very lengthy operation...

    NSLog(@"%@", string); //is it safe?
    });
}

Мне интересно, если это правильно, потому что я думаю, что я должен был сохранить строку до выполнения блока: на самом деле я боюсь, что цикл обработки событий завершается и отправляет string сообщение об автоматическом выпуске перед использованием string в блоке , Это может привести к сбою программы.

Я прав? Должен ли я отправить сообщение об удержании и выпуске на string или это правильная реализация? Заранее спасибо!

Ответы [ 2 ]

5 голосов
/ 13 февраля 2011

Мне интересно, если это правильно, потому что я думаю, что я должен был сохранить строку перед выполнением блока: на самом деле я боюсь, что цикл обработки событий завершается и отправляет строку сообщение об автоматическом освобождении перед использованием строки в блоке.

Не бойся:
Блок захватывает область действия окружающего метода / функции в том смысле, что он автоматически retain определяет любую переменную объекта, которая используется внутри блока. Помните об этом, когда вы используете self внутри блока, так как это может сильно повлиять на время жизни объекта!

Существует одно исключение из этого правила, и это переменные, объявленные как

__block SomeObjectPointerType variableName

Обновление

Поскольку есть новый комментарий к этому ответу, я, вероятно, должен добавить, что с появлением ARC все немного изменилось:

В ARC все переменные объекта по умолчанию имеют значение __strong, и это также относится к переменным, отмеченным __block. Если вы хотите избежать сильного захвата переменной в блоке, вы должны определить локальную переменную __weak.

Конец обновления

Если вы хотите узнать больше о блоках, bbum дал отличную сессию под названием Представление блоков и Grand Central Dispatch на iPhone на WWDC 2010.

Раздел «Сведения о блоке» начинается в 11:30.

0 голосов
/ 13 февраля 2011

беспокойство; когда будет выпущен объект авто-релиза?

NSString *myString= [NSString stringWithFormat: @"%@", stringVariable];

myString зависит от stringVariable, всякий раз, когда stringVariable освобождает myString, немедленно освобождается.

NSString *myString= [NSString stringWithString: @"stringVariable"];

На практике наблюдается, что myString может быть выпущена сразу после завершения метода.

Теперь, если вы измените свой код и используете NSAutoReleasePool

- (void)method {
    NSAutoreleasePool pool = [[NSAutoreleasePool alloc] init];

    NSString *string= [NSString string]; //will be autoreleased

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    //very very lengthy operation...

    // string will be released here
    [pool release];

    NSLog(@"%@", string); // it is not safe?
    });
}

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

- (void)method {
    NSAutoreleasePool pool = [[NSAutoreleasePool alloc] init];

        // lengthy operations ...
    [pool release];
}
...