Reputation: 10129
I am doing an application which downloads image from server and displays it on a view. I am using delegate for that. Once the image is finished loading a delegate sends message to the view to show the image.
The above scenario is working fine. But if I move out from that particular view to any other view, when the image loading is finished the delegate tries to send message and causes an error.
I tried setting the
imageFetcher.delegate=nil;
in view didUnload. Also before calling the delegate method in download class I check for delegate is nil.
But i can see that the delegate object is not nil.
if(delegate!=nil)
{
[delegate imagefetcherView:self didLoadImage:image];
}
How can I fix this error?
Thanks
Upvotes: 2
Views: 4025
Reputation: 18816
I would implement a separate cache to temporarily store the picture in care view controller is deallocated but the picture can be used once again, e.g. if the user gets back to the same page.
In that case you would have a long-lived cache object as a delegate
. View controllers can, for example, subscribe to receive key-value notifications about incoming pictures when those view controllers become visible (just don't forget to unsubscribe from KVO in viewWillDisappear
).
If your controller is invisible but likely to be shown again you'll have the picture in cache (to be dropped if low memory); of course you can also check in the cache if your picture is never likely to be shown again and drop the picture.
Upvotes: 0
Reputation: 152
You still can have a dealloc call in your class but it should not call [super dealloc]. If you add it you can set up a breakpoint here and see from where its gets its retain count to 0. Or use Instruments to track retain/release cycle of your controller.
Upvotes: 0
Reputation: 437632
Do not rely viewDidUnload
to do any cleanup. That's only called in iOS versions prior to iOS 6, and only when the view is unloaded due to memory pressure (but not when you just dismiss/pop the view).
Set your delegate to nil
in the dealloc
method or viewDidDisappear
or wherever is appropriate.
Two caveats relevant to picking which method you'll nil
the delegate
:
Be aware that viewWillDisappear
and viewDidDisappear
will also be called if you push/present another view controller, even if the current one has not been yet been dismissed. Only rely upon these disappear-related methods if the view controller in question does not ever push/present another view controller.
If employing the dealloc
technique, note that this only works if the delegate
is a weak
property of the image fetcher class (and delegates generally should be weak
). If the delegate
was a strong
or retain
property, that will prevent the view controller's dealloc
from ever getting called.
By the way, I gather that you are letting the image fetch continue, even though the view controller has been dismissed. You might want to not only nil
the delegate, but cancel the request, too. It depends upon whether (a) you're using a fetch that even permits a cancellation (e.g. a NSURLConnectionDataDelegate
approach or a AFNetworking operation) and, if so, (b) whether you want it to cancel or not. It's easy, though, to tie up precious network resources (esp if on a slow cellular connection) letting requests continue even if the user doesn't need it anymore. It depends upon the particulars of your app.
Regardless, do not rely upon viewDidUnload
.
Upvotes: 7
Reputation: 21805
viewDidUnload
isnt called in iOS 6+.
you should use this
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
imageFetcher.delegate=nil;
}
Upvotes: 3