Проверка, был ли объект освобожден перед отправкой ему сообщения - PullRequest
5 голосов
/ 02 июня 2010

Я только недавно заметил сбой в одном из моих приложений, когда объект пытался отправить сообщение своему делегату, а делегат уже был освобожден.

В данный момент, перед вызовом любых методов делегата, я запускаю эту проверку:

if (delegate && [delegate respondsToSelector:...]){
   [delegate ...];
}

Но, очевидно, это не учитывается, если делегат не равен нулю, но был освобожден.

Помимо установки делегата объекта равным nil в методе делегата dealloc, есть способ проверить, был ли делегат уже освобожден, только если у меня больше нет ссылки на объект.

Ответы [ 4 ]

16 голосов
/ 02 июня 2010

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

8 голосов
/ 02 июня 2010

Я полагаю, вы не используете GC. В этом случае стандартное соглашение состоит в том, что код, который устанавливает делегата, отвечает за установку ссылки делегата-пользователя на nil, прежде чем разрешить делегату быть освобожденным. Если вы используете GC, вы можете использовать ссылку __weak для делегата, позволяя сборщику мусора установить ссылку на nil, когда экземпляр собирается как мусор.

0 голосов
/ 10 апреля 2013

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

-(oneway void)release
{
    NSLog(@"release called");
    [super release];
}
0 голосов
/ 02 июня 2010

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

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