Delegate method call, unrecognized selector, because sending to the wrong object

In my application, I do network booting. My data model consists of "Loader" objects that do this loading and call their delegate on completion / failure. All delegates comply with the LoaderDelegate protocol.

The problem I am facing is that sometimes seemingly random objects, rather than a delegate, receive delegate messages. This, of course, causes a crash due to an unrecognized selector.

Only one set of crash logs tells me which of my bootloaders has a problem, others do not have this information, just a random object that received the message.

I am stuck on how to determine the real cause of this problem.

One set of crash logs has a bootloader trying to call it a delegate, but reaching _UIImageViewExtendedStorage . Another has a bootloader that reaches __NSCFInputStream . Another __NSBlockVariable__ . And one more, CALayer .

And this is only in my latest beta from 3 days ago.

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

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

+4
source share
2 answers

It turns out I was getting this error randomly everywhere, just not in this particular class, and not just using delegation methods.

In my case, the problem was that I was accessing the properties of various classes in multiple threads, and these properties were non-atomic. Since I fixed this (remote non-atomic attribute of properties), I did not see this anymore.

+2
source

Please post the code because it is difficult to eliminate. Remember to leave the delegate in dealloc.

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

The more you need to delegate a delegate, do not save it, but this is not a problem in your situation.

 @property (assign) id<TheMightyDelegate> delegate; 

Another thing you must do is ensure that the delegate responds to the selector that you want to send to it before you run this method.

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

Hope this puts a light on your problem. If not, enter the code.

+4
source

Source: https://habr.com/ru/post/1384494/


All Articles