Ben Baron
Ben Baron

Reputation: 14815

Calling delegate method, unrecognized selector because sending to wrong object

In my app I do a lot of network loading. My data model consists of "Loader" objects that do this loading and call their delegate when finished/failed. The delegates all conform to a "LoaderDelegate" protocol.

The issue I'm having is that sometimes seemingly random objects, not the delegate, are getting the delegate messages. This of course causes a crash because of an unrecognized selector.

Only one set of crash logs tell me which one of my loaders is having the issue, the others don't have that information, just the random object that got the message.

I'm stuck at how to determine the real cause of this issue.

One set of crash logs has a loader trying to call it's delegate but reaching _UIImageViewExtendedStorage. Another has a loader is reaching __NSCFInputStream. Another __NSBlockVariable__. And yet another, CALayer.

And that's just in my latest beta from 3 days ago.

It would be one thing if it was the same object each time, but it seems almost random. Is it possible that memory is getting overritten with a new object somehow?

My delegate property for all of my loaders is an assign property, but the delegate is always alive when the loader finishes (delegates are my view controllers calling the loaders).

Upvotes: 4

Views: 2047

Answers (2)

Ben Baron
Ben Baron

Reputation: 14815

Turns out I was getting this error randomly all over the place, just not in this particular class and not just with delegate methods.

In my case, the problem turned out to be that I was accessing properties of various classes in multiple threads and those properties were nonatomic. Since I fixed that (removed nonatomic attribute of the properties), I haven't seen this happen anymore.

Upvotes: 2

Rafał Sroka
Rafał Sroka

Reputation: 40030

Please post some code, cause it is hard to troubleshoot. Remember to nil your delegate in the dealloc.

- (void) dealloc {
  objectOfWhichIAmTheDelegate.delegate = nil;
}

What is more you the delegate should be an assign property not retain - but that's not a problem in your situation.

@property (assign) id<TheMightyDelegate> delegate;

Another thing you should do is to guarantee that the delegate responds to the selector you want to send to him before you fire the method.

if ([delegate respondsToSelector:@selector(yourMethod)]) {
[delegate performSelector:@selector(yourMethod)];
}

Hope this will put some light on your problem. If not please provide some code.

Upvotes: 4

Related Questions