2015-03-19 1 views
5

У меня есть ситуация, в которой я пытаюсь решить эти Crashlytics проблемы и у меня есть этот журнал сбоевИОС: EXC_BAD_ACCESS для WebView делегата

Thread : Crashed: com.apple.main-thread 
0 libobjc.A.dylib    0x34217f46 objc_msgSend + 5 
1 UIKit       0x29a2d5a3 -[UIWebView webView:decidePolicyForNavigationAction:request:frame:decisionListener:] + 182 
2 CoreFoundation     0x2630cad4 __invoking___ + 68 
3 CoreFoundation     0x26239645 -[NSInvocation invoke] + 300 
4 CoreFoundation     0x2623d0c7 -[NSInvocation invokeWithTarget:] + 50 
5 WebKitLegacy     0x326d9261 -[_WebSafeForwarder forwardInvocation:] + 224 
6 CoreFoundation     0x2630b62f ___forwarding___ + 354 
7 CoreFoundation     0x2623d008 _CF_forwarding_prep_0 + 24 
8 CoreFoundation     0x2630cad4 __invoking___ + 68 
9 CoreFoundation     0x26239645 -[NSInvocation invoke] + 300 
10 WebCore      0x31c02729 HandleDelegateSource(void*) + 100 
11 CoreFoundation     0x262cefbf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14 
12 CoreFoundation     0x262ce461 __CFRunLoopDoSources0 + 364 
13 CoreFoundation     0x262cca35 __CFRunLoopRun + 772 
14 CoreFoundation     0x2621a3b1 CFRunLoopRunSpecific + 476 
15 CoreFoundation     0x2621a1c3 CFRunLoopRunInMode + 106 
16 GraphicsServices    0x2d801201 GSEventRunModal + 136 
17 UIKit       0x2988443d UIApplicationMain + 1440 
18 abc       0x0030dcd7 main (main.m:14) 

Я понимаю, что некоторые его обратного вызова на WebView делегата и плохое превышение произошло , поэтому, чтобы исправить это, я обработал делегатов через

[self.webview stopLoading]; 
self.webview.delegate =nil; 

во всех классах, но я вижу этот сбой. Можете ли вы рассказать мне, что, возможно, не так, и какой-то подход исправить это?

+0

Здравствуйте @AnkitSachan, в какой строке вы поэтапному этот вопрос? вы отлаживаете весь код с точкой останова в своем классе? –

+0

@ParasJoshi Я получаю эти журналы сбоев от crashlytics, и есть много веб-просмотров в базе кода, поэтому я не могу фактически отлаживать, но я проверял, что код сделал сухую работу, и все, кажется, работает нормально –

+1

Ankit, пожалуйста, объясните больше о вашей проблеме. Многие веб-представления означают? –

ответ

-1

UIWebView s delegate использует assign, а не weak. Поэтому вам необходимо аннулировать delegate, когда контроллер webView освободится.

Пример:

- (void)dealloc 
{ 
    self.webview.delegate =nil; 
} 
+0

@kindly прочитал полный вопрос, который уже был выполнен –

+0

Я прочитал полный вопрос. Вы говорите, что вы «обрабатываете делегатов через ...», но не указали, что вы также сворачиваете веб-представление в 'dealloc'. – tubtub

+0

Уважаемый @tubtub sir, даже если я не делаю этого в dealloc, а где-то еще в коде, это должно быть хорошо? хотя, если быть точным, я справился с этим в dealloc –

-1

Вы добавляете веб-просмотра в пределах вашего подкласса веб зрения? Как правило, это проблема, и если это так, изменение суперкласса в UIView решит проблему.

+0

Привет, Chihan, Спасибо за обновления, но это не так. У меня есть контроллер представления, который владеет этим веб-просмотром. –

-1

Использовать визу наоборот означает сначала нулевой делегат, а затем после остановки загрузки веб-представление может вам помочь.

такой.

[_webView setDelegate:nil]; 
[_webView stopLoading]; 

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

+0

попробовал это без успеха. –

+0

Зачем голосовать? что-то не так в этом ответе ..? –

-1

Используйте вместо [прослушиватель], чтобы сообщить свой UIWebView для обработки щелчка по URL-адресу.

-(void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener 
{ 
    [listener use] 
} 
+0

Приложение Devloper разрушает причину плохого доступа (т. Е. Celanup веб-просмотра и делегата не обрабатывается должным образом) не из-за реализации метода делегата, которые в любом случае необязательны –

1

Попробуйте отключить скроллинг поведение вашего UIWebView в перед ViewController deallocs это

for (id subview in webView.subviews){ 
    if ([[subview class] isSubclassOfClass: [UIScrollView class]]){ 
     [subview setContentOffset:CGPointZero animated:NO]; 
    } 
} 

P.S.Подход Dipen Chudasama является правильным, согласно документации Apple, вы действительно должны установить свойство делегата всухую перед выпуском WebView, при условии, что вы правильно выпустили WebView внутри dealloc функции, но не viewWillDisappear

11

Следующая может быть в данном случае

  • Пользователю предоставляется экран с UIWebView
  • UIViewController Устанавливает self как делегата веб-страницы начинает загрузку
  • Пользователь покидает экран
  • UIViewController получает высвобожденыUIWebView завершает загрузку и посылает Я завершил загрузку сообщение своему делегатом

или

какой-либо другой метод делегата вызывается, когда Веб-объект объекта не более. Видно, что эффект висячего указателя

1.Alway s убедитесь, что вы остановить загрузку Webview и удалить делегат перед тем оставляя вид

Перед отпуская экземпляр UIWebView, для которого вы установили делегата, вы должны сначала установить его имущество делегата до нуля. Это может быть сделано , в вашем dealloc методе

Вот reference

// If ARC is used 
- (void)dealloc { 
    [_webView setDelegate:nil]; 
    [_webView stopLoading]; 
} 

// If ARC is not used 
- (void)dealloc { 
    [webView setDelegate:nil]; 
    [webView stopLoading]; 
    [webView release]; 
    [super dealloc]; 
} 

// ARC - Before iOS6 as its deprecated from it. 
- (void)viewWillUnload { 
    [webView setDelegate:nil]; 
    [webView stopLoading]; 
} 

2.Make, что вы не stopLoading и setDelegate к нулю в viewWillDisappear

, если ViewController является дочерним элементом другого ViewController, u может вызвать удаление ViewController's с родителя ViewController's view с анимацией. В то же время u может удалить ViewController от своего родителя и nil вне его ссылка. в этот момент ViewController будет nil и viewWillDisappear будет никогда назвать, означая WebView делегат никогда не будет очищены

Использование dealloc и убедитесь, что ваш WebView всегда очищены.

3.Make, что вы установили ContentOffset в subviews от webview к CGPointZero без анимации

В IPad в некоторых версиях в то время как WebView прокрутки, если вы закроете родитель ViewController без установки ContentOffset к CGPointZero этот вопрос возникнет.

, так что лучше вам позвонить Следующий код в родительском ViewController перед закрытием

for (id subview in webView.subviews){ 
     if ([[subview class] isSubclassOfClass: [UIScrollView class]]){ 
      [subview setContentOffset:CGPointZero animated:NO]; 
     } 
    } 

Надеются, что это helps.Feel спросить ваши сомнения.

4.Всего Вы не должны embedUIWebView объектов в UIScrollView объектов. Если вы это сделаете, то может произойти непредвиденное поведение , потому что события касания для двух объектов могут быть перемешаны и неправильно обработаны.

Вот reference

+1

Вообще говоря, если вы имеете дело с проблемой управления памятью, такой как EXC_BAD_ACCESS.It всегда полезно включить NSZombies в xcode и проверить все, и вы можете попробовать такие инструменты, как статический anaylser ... использование этих возможностей позволит вам поймать ошибки раньше, чем пользователь узнает об этом. –

+0

Большое спасибо! Я пытался понять, почему мои методы делегатов никогда не вызывались и, наконец, знали, почему. Я создал экземпляр моего класса подключения (который в потоках и делегат (self)) внутри метода и не хранил ссылку на него. Таким образом, GC, кажется, удаляет экземпляр сразу после открытия соединения, и поэтому делегат никогда не вызывался. –

+1

Добро пожаловать. В iOS нет GC, ARC выполняет задание. Проверьте, соответствует ли вам делегат, и убедитесь, что вы установили экземпляр делегата самостоятельно. –