Я кодирую библиотеку (Obj-C для iPhone), которую я хочу упаковать и продать, поэтому мне, очевидно, нужно проработать любые дизайнерские изгибы, прежде чем выставлять их на продажу.Я также использую эту библиотеку, чтобы помочь мне разработать другое приложение.
Моя библиотека в значительной степени построена на делегировании задач.Основная функция, которую я имею, состоит в том, чтобы запустить (потенциально) длительный процесс, и когда он закончится, я вызываю метод Protocol делегата в делегате класса.
Дополнительным усложняющим фактором здесь является то, что я часто планирую запускать эту задачу каждые 30 секунд или около того.Обычно я делаю это с помощью [self executeSelector: @selector (someMethod :) withObject: nil afterDelay: 30], а не с помощью NSTimer.Затем, когда метод делегата успешно возвращается, я обрабатываю возвращенные данные и запускаю метод через 30 секунд.Это дает мне 30 секунд между вызовами метода, а не 30 секунд от начала одного вызова до следующего.(Это в основном на тот случай, если вызов когда-либо займет более 30 секунд, что не должно происходить.)
Ошибка, которую я улавливаю, заключается в том, что иногда метод обратного вызова Delegate завершается с ошибкой EXC_BAD_ACCESS,На основании моего расследования выяснилось, что представитель моей библиотеки классов исчез (был освобожден / освобожден) с тех пор, как начался длительный процесс.Таким образом, когда он вызывает [[self Delegate] doSomeDelegateMethod], он обращается к освобожденному объекту.
Я попытался сначала проверить [[self Delegate] responsedsToSelector: @selector (doSomeDelegateMethod)], но даже этот доступ, очевидно, также вызываетEXC_BAD_ACCESS.
Пока еще не кажется, что проверка [self Delegate] == nil также является правильным способом.
Один из способов, по-моему, я решил проблему,в этом конкретном случае, когда контроллер представления, который создает мой объект, исчезает (и, следовательно, на пути к свалке мусора), я вызываю [NSObject cancelPreviousPerformRequestsWithTarget: self].Это, видимо, решает проблему.(Означает ли это «исправление» также, что мой объект «знает» о предстоящем вызове и сохраняет себя в памяти до тех пор, пока не сможет успешно, отчаянно выстрелить своим последним выстрелом?)
Кажется, это ставит полосуна пулевой ране.Да, похоже, что это мешает моему приложению сломаться на этот раз, но моя интуиция говорит мне, что это плохое решение.
Я также рассмотрел возможность установки пользовательского объекта равным nil в моем viewWillDisappear: animated: method,что, вероятно, является правильным шаблоном кодирования, но кажется неправильным, что клиент должен быть настолько точным в обращении с моими объектами.
Что меня действительно беспокоит, так это то, что я, как разработчик библиотеки, еще не нашел способа «вставить» мой код, чтобы он не вызывал исключения для пользователя, если онине делай только правильные вещи.В принципе, я хотел бы получить мой объект:
- Получить запрос.
- Перейти искать ответ.
- Найти ответ.
- Попробуйте вернуть ответ.
- Поймите, что на другом конце ничего нет.
- Сдайтесь и умрите сами по себе.(Хорошо, так что «умереть самому», вероятно, не произойдет, но вы понимаете, в чем дело.)
Один интересный побочный момент:
Основная причина, по которой я могу предотвратитьЭтот тип ошибки происходит следующим образом:
Я сделал следующие шаги:
- Построил файлы моей библиотеки .h / .m.
- Сгенерировал свою библиотеку.выходной файл.
- Импортировал файлы моей библиотеки .a / .h в другой проект.
- Произошла ошибка, описанная выше.
- Получил возможность просмотреть код из одного изФайлы .m, которые СЛЕДУЕТ скрывать внутри файла .a.
Я что-то здесь упускаю?Действительно ли я рискую раскрыть весь свой исходный код, если он когда-нибудь выдаст ошибку для клиента?(Это всего лишь побочный вопрос, но я здесь весьма обеспокоен!)
Спасибо за любую помощь, которую вы можете оказать, чтобы помочь мне стать лучшим программистом!
--- EDIT ---
Я нашел другую причину, почему это важно. В другом контроллере представления, где я использую эту библиотеку, я реализовал стратегию NSTimer. Если представление извлекается из стека навигации (то есть в viewWillDisappear: animated: метод), я делаю недействительным указанный таймер. Таким образом, после исчезновения представления в мою библиотеку больше не будут поступать звонки.
Вот в чем проблема: что, если представление исчезнет В СРЕДНЕМ продолжительного вызова? Да, это сложно и маловероятно, но я просто произвел это на симуляторе. В частности, THIS - вот почему я ищу обходной путь, который позволит моему коду понять: «эй, на другом конце этого канала ничего нет», а затем изящно провалиться. Кто-нибудь?
Спасибо!