2013-10-25 2 views
1
void f(NSString *s) 
{ 
    [someObj doSomethingWithCompletionHandler:^() 
    { 
     doSomethingElse(s); 
    }]; 
} 

void g() 
{ 
    NSString *s = [[NSString alloc] initWith....]; 
    f(s); 
    [s release]; 
} 

Есть ошибки в данном коде? Я думаю, s может быть уничтожен до того, как будет выдан completionHandler, и мусор будет передан в doSomethingElse. Я прав? Если да, то как мне его исправить?Управление памятью какао-памяти

ответ

2

Нет, это нормально, блок сохраняет s. Таким образом, s не освобождается при звонке [s release].

Дополнительная информация: вы можете столкнуться с проблемами при создании цикла сохранения. Чаще всего это выглядит так:

[self doSomeThingWithCompletionHandler:^() 
{ 
    [self beHappy]; 
} 

Самостоятельно сохраняет блок, блок сохраняет себя, вуаля. Но это не должны быть настолько очевидны:

NSDictionary *dictionary = @{@"someKey" : someObj, @"someOtherKey", someOtherObj}; 
// 
// lots of stuff happening here 
// 
[someObj doSomethingWithCompletionHandler:^() 
{ 
    id someOtherObj = dictionary[@"someOtherKey"] 
}] 

Решение объявить слабую переменную:

__weak id weakSelf = self; 
[self doSomethingWithCompletionHandler:^() 
{ 
    //and to make sure it stays valid if you do multithreaded stuff 
    __strong id strongSelf = weakSelf; 
    [strongSelf beHappy]; 
}]; 

редактирования: как указано в комментариях, оригинальный пост был использованием не- Код ARC. В этом случае вам необходимо заменить __weak на __unsafe_unretained

+0

__weak доступен только с ARC, но OP использует ручной подсчет ссылок. –

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