[self retain], [self autorelease], это правильно, когда меня назначают делегатом? - PullRequest
0 голосов
/ 05 августа 2011

Я решил проблему с помощью чего-то, что звучит странно: «Вызовы [self retain] и [self autorelease]».

Вот случай:

MyObject является подклассом UIView,поэтому обычно он выделяется, помещается в стек представления и освобождается.MyObject также имеет таймер, который удалит себя из суперпредставления.Таким образом, в основном MyObject может быть освобожден в любое время.Помимо отображения классных вещей, MyObject также может отображать UIAlertView и ожидает выбора пользователя, поэтому он является делегатом alertView.Проблема в том, что если пользователь делает выбор после освобождения MyObject ... ну, вы знаете EXC_BAD_ACCESS, я думаю ...

Так что я мог бы сохранить ссылку на AlertViews (да, есть несколько),и установите для делегата значение nil в методе Mylocity Deloc.Но тогда я не смог обработать выбор (а так как их несколько, это сделало бы больше переменных, которые мне не нравятся.

Итак, что я сделал:

//alertView creation
-(void)showAlert{
    [self retain];

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"title"
    message:@"message" 
    delegate:self 
    cancelButtonTitle:@"No"
    otherButtonTitles:@"Yes",nil];

    [alertView show];
    [alertView release];
}

//Delegate method
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    [self autorelease];
    // Do the job
}

Я знаю, что это нехорошо, я написал много комментариев по этому поводу, чтобы другие разработчики, которые будут повторно использовать код, были осторожны, но я не вижу другого варианта. Это правильно? Есть ли лучший способ сделать это?

Ответы [ 4 ]

1 голос
/ 05 августа 2011

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

1 голос
/ 05 августа 2011

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

0 голосов
/ 05 августа 2011

Не можете ли вы сделать alertView переменной @property или instance и просто установить alertView.delegste = nil в MyObject's dealloc?

0 голосов
/ 05 августа 2011

Прежде всего, я не вижу проблемы с удержанием себя. Я также сделал это в некотором многопоточном коде. Возможно, не лучшее решение, но оно сработало.

Теперь, если вы хотите избежать [само удержания], подумайте о следующем: Возможно, вместо прямого освобождения при срабатывании таймера, вместо этого вы проверяете, есть ли предупреждение. Если нет, отпустите. Если да, спрячьте представление (но не удаляйте из суперпредставления) и установите в новом иваре флаг, что объект должен быть удален из суперпредставления. В обратном вызове листа установите флажок и, если он установлен, удалите представление из суперпредставления, освободив его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...