Я только недавно заметил катастрофический отказ в одном из моих приложений, когда объект пытался передать своего делегата, и делегат был уже выпущен.
В данный момент, прежде, чем назвать любые методы делегата, я осуществляю эту проверку:
if (delegate && [delegate respondsToSelector:...]){
[delegate ...];
}
Но очевидно это не составляет, если делегат не является нолем, но был освобожден.
Помимо установки делегата объекта в ноле в делегате dealloc
метод, там способ проверить, был ли делегат уже выпущен, просто упаковывают, у меня больше нет ссылки на объект.
Нет. Нет способа определить, указывает ли переменная на правильный объект. Вам нужно построить свою программу так, чтобы делегат этого объекта не уходил, не сообщив ему об этом.
как насчет использования счетчика, который вы увеличиваете каждый раз при выделении и уменьшаете каждый раз при освобождении. Таким образом вы можете обнаружить двойные аллоки и решить не использовать делегат, если счетчик не равен нулю, но адрес также не равен нулю
Я полагаю, вы не используете GC. В этом случае стандартное соглашение заключается в том, что код, устанавливающий делегата, отвечает за установку ссылки пользователя-делегата на nil
перед тем, как разрешить делегату быть освобожденным. Если вы используете сборщик мусора, вы можете использовать ссылку __ weak
для делегата, позволяя сборщику мусора устанавливать ссылку на nil
при сборке мусора.