iOS - EXC_BAD_ACCESS code = 1 UIWebView аварийно завершает работу после (метод переворота) init
Я просто переключил свое приложение на ARC. Переход был частично успешным благодаря инструменту рефакторинга, который предоставляет XCode. Одна часть, которая не работает, является странной ошибкой.
Я использовал метод swizzling (method_exchangeImplementations), чтобы вместо вызова initWithFrame из UIView он вызывал мой код myInitWithFrame. Процесс рефакторинга выдал ошибку при объявлении метода myInitWithFrame, поэтому я добавил атрибут__((objc_method_family (init))) после объявления метода. Теперь все это прекрасно работает для iOS 6.0 и выше, но на iOS 5.0 (самая низкая iOS, которую я бы хотел поддерживать) не работает. Я получаю EXC_BAD_ACCESS (код =1, адрес =0X28). При каждом запуске появляется один и тот же адрес памяти.
У меня есть UIWebView, который вызывает это:
[[UIWebView alloc] initWithFrame:webViewFrame];
После того, как myInitWithFrame выполнит свою инициализацию, он возвращает себя, а затем вылетает. В трассировке потока говорится, что происходит сбой в коде яблок (метод выделен серым цветом) в методе [UIWebView retain], как показано ниже.
Thread 1, Queue : com.apple.main-thread
#0 0x3515a7d2 in -[UIWebView retain] ()
#1 0x316ddef4 in objc_retain ()
#2 0x0011528c in -[UIView(style) myInitWithFrame:]
Извините, что трассировка потока не очень хорошо отформатирована, мне не хватает представителя для публикации изображения.
Есть ли причина, по которой тот же код работает для iOS 6.0, но не для iOS 5.0?
1 ответ
Эту проблему было очень сложно исправить. Тот факт, что эта проблема обнаруживалась только на iOS 5, а не на iOS 6, был моим первым признаком того, что это может быть проблема с яблоком или проблема, связанная с использованием метода. Примерно через неделю поиска я пришел к согласию, что мне следует обратиться в службу технической поддержки Apple, чтобы узнать, могут ли они помочь мне с этой проблемой.
Они ответили, что это наши недостатки. Он сказал, что в iOS 5 UIWebView отслеживает свой собственный счетчик хранения (используя класс UIWebViewInternal) и что мой метод Swizzling удерживал объект до его полной инициализации, и это вызывало сбой. Когда я не использовал ARC, это не было проблемой, потому что я никогда не вызывал retain в функции init, но с ARC он добавляет retains по своему усмотрению. Он упомянул, что в iOS 6 UIWebViews не управляют своим собственным счетом хранения, и именно поэтому он работал в iOS 6.