1

I have a view, which is subclass of UIWebView. It has a property called Contact which is a managed object. The view uses templating engine to create a html with the object and then load into UIWebView. I thought it would be a better idea to monitor the object in the view itself, such that whenever something changes in the object, the view refreshes automatically. So, observed for certain attributes of the managed object in the view itself. And then to avoid the notification coalesce, I have made it such that the reload is done with

[self performSelector:@selector(refresh) afterDelay:0 ].

It refresh the webview automatically whenever it finds the change but also gives some strange crash. The crash says [MyWebView retain] message sent to deallocated object. I know I have properly removed observing values in dealloc method. But, it seems like dealloc gets triggered after a while. I have a strange issue related to releasing the view. The view stays for a while, although the view controller is already released and then releases after may 2/3 seconds. It is really strange. I think the crash is because of this.

Please do suggest me any idea. I will be glad to hear your suggestion. There are something wrong certainly, if anybody could point me I would really be grateful.

  • Try with setting all possible delegates (From WebView and etc) to nil before deallocation. Sometimes delegate method can be fired up after object deallocation. – Ivan Alek Jan 23 '13 at 17:20
  • See this post for more info about why nil may be what you need: http://stackoverflow.com/a/1564419/135557 – Monte Hurd Jan 23 '13 at 17:53
  • have u tried setting one of the references as weak? preferably the one that is independant of the object, so even when your message is sent, a message to nil is fine. – Pochi Jan 23 '13 at 17:55

1 Answers1

0

Using the delegate design pattern can cause EXC_BAD_ACESS KERN_INVALID_ADDRESS crashes if not used properly. If you have processing that is running in background threads that use the delegate design pattern, where in the object you set SELF as the delegate then you must remove SELF as the delegate in the dealloc method (even under ARC) by setting the delegate reference to nil, or there is a possibility that the object will try to call back into your deallocated object using the delegate design pattern. So if you have something like this in your object.

[_xmlParser setDelegate:self];

you should always have a dealloc method even under ARC to prevent the possibility of a crash in the case where your object gets destroyed while still doing work. It is very common to have your object destroyed while doing work. imagine a UIViewController that shows images from the internet. If you had a FetchImage class that used the delegate design pattern to lookup images that then calls a routine on the object when the lookup finishes, it is easily for the user to pop into and out of your UIViewController while your FetchImage object is still doing work on the background thread. You might not ever notice this when testing, but if you have hundreds of users, some of them will notice because the app will crash when your object tries to call a method on the SELF reference.

If your object uses the delegate design pattern, always have this to cleanup:

#pragma mark - dealloc - cleanup delegate references to prevent callbacks into deallocated objects (EXC_BAD_ACCESS / KERN_INVALID_ADDRESS)

- (void)dealloc
{
    [_xmlParser setDelegate:nil];
    // for non ARC based code you would also call: [super dealloc]; 
}

search every class in your project, if you have setDelegate:self or delegate = self then your users are most likely experiencing race condition crashes with your app if you don't have a dealloc cleanup method as described above. If you don't have the dealloc, add it even if you never see crashes when testing. -rrh

Richie Hyatt
  • 2,244
  • 2
  • 21
  • 14