iOS проверяет, существует ли делегат до вызова метода - PullRequest
5 голосов
/ 02 ноября 2011

Я пишу приложение для iOS и использую библиотеку imageStore, чтобы лениво загружать изображения и кэшировать их в памяти. (https://github.com/psychs/imagestore)

В ViewController я создаю экземпляр imagestore:

imageStore = [ImageStore new];
imageStore.delegate = self;

Когда изображение загружено успешно, метод делегата вызова imagestore

- (void)imageStoreDidGetNewImage:(ImageStore*)sender url:(NSString*)url

что делает reloadData на просмотр таблицы для перерисовки ячеек. Все работает хорошо. Но есть проблема: если ViewController didUnload (вернуться в контроллер навигации) и изображение загружены, приложение завершается сбоем, потому что метод imagestore вызывает метод выгруженного ViewController.

Я пытаюсь сделать следующее: 1) в ViewController я помещаю этот код в раздел viewDidUnload:

imageStore.delegate = nil;
imageStore = nil;

2) В imageStore я добавил проверку на nil:

if(delegate != nil) {
  ...call delegate method
}

Работает, но приложение все равно периодически вылетает.

Ответы [ 2 ]

12 голосов
/ 02 ноября 2011

Попробуйте поместить этот код в раздел dealloc.

imageStore.delegate = nil;
imageStore = nil;

Точно так же предложение if не является необходимым, поскольку любой вызов объекта nil игнорируется приложением, поэтому, если у вас есть что-то вроде этого:

id delegate = nil;    
[delegate callAnyMethod];

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

if([delegate conformsToProtocol:@protocol(yourProtocolName)] && [delegate respondsToSelector:@selector(imageStoreDidGetNewImage:url:)]) {
       [delegate imageStoreDidGetNewImage:imageStore url:url];
}

Ура!

0 голосов
/ 02 ноября 2011

Это работает, но приложение периодически все равно падает.

Это противоречие.Существует две возможности:

  1. Ваше исправление сработало, и приложение по какой-то другой причине зависало.

  2. Ваше исправление не сработало,приложение продолжает аварийно завершать работу по той же причине, по которой оно было и раньше.

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

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