Unrecognized Selector Sent to Instance Swift 3

unrecognized selector sent to instance - Swift 3

In Swift 3 use the #selector syntax

self.displayLink = CADisplayLink(target: self, selector: #selector(tick))

In Swift 4 additionally you have to insert @objc at the beginning of the action

@objc func tick(...

unrecognized selector sent to instance when i call from another class

What you need to do is to select target accordingly

     var orderViewCard = OrderVC()

let tapGestureRecognizer = UITapGestureRecognizer(target: orderViewCard, action: #selector(orderViewCard.handleCardTap))
orderViewCard.handleArea.addGestureRecognizer(tapGestureRecognizer)

unrecognized selector sent to instance after Swift 4.2 migration

Change

func reusablePickerViewController

to

@objc func reusablePickerViewController

The migration from Swift 3 to Swift 4.2 changed the rules for how instance members are exposed to Objective-C. In Swift 3, they were exposed by default. In Swift 4.2, you must expose them explicitly; otherwise, Objective-C cannot see them — which is exactly what is happening to you. The method is there, but Objective-C thinks it isn't, so it crashes with an Unrecognized Selector exception.

[_LSDefaults sharedInstance]: unrecognized selector sent to class 0x20cbf3aa0

I found the root cause:

Added NSSetUncaughtExceptionHandler to find the following stack trace.

2019-12-18 16:37:55.892789+0530 XXXXX[2603:645006] Stack Trace: (   
0   CoreFoundation                      0x00000001c51249a0 DA838E75-6B30-360E-9661-C4800A7E1BF6 + 1227168
1   libobjc.A.dylib                     0x00000001c4e4d0a4 objc_exception_throw + 56
2   CoreFoundation                      0x00000001c502ccc8 DA838E75-6B30-360E-9661-C4800A7E1BF6 + 212168
3   CoreServices                        0x00000001c578f50c 4631A29A-FFB2-3A9D-95FF-1037507BD066 + 840972
4   Foundation                          0x00000001c53df908 0DF2911E-80CB-3289-8A1E-ED0913D55A12 + 43272
5   CoreFoundation                      0x00000001c512ad90 DA838E75-6B30-360E-9661-C4800A7E1BF6 + 1252752
6   CoreFoundation                      0x00000001c4ffabd0 DA838E75-6B30-360E-9661-C4800A7E1BF6 + 7120
7   XXXXX                               0x00000001086d3cc0 - **[ONIMehtodId invokeWithTarget:Target:parameter:result:]** + 4372
8   XXXXX                               0x00000001086d6b88 fdwPRGInHj7S + 140
9   XXXXX                               0x00000001086e02ac fdioJuJ5X8sy + 60
10  XXXXX                               0x00000001086dfe40 fdfAYA5Knk6m + 1180
11  XXXXX                               0x00000001086df998 fderBiHVLVSO + 132
12  XXXXX                               0x00000001086db524 fdpriAImFRX8 + 5820
13  XXXXX                               0x00000001087375ac 10Qp8Dl9pVnp + 440
14  XXXXX                               0x00000001087300b8 108jVd8JFekR + 232
15  XXXXX                               0x00000001087a9594 10uqENVjb5qq + 244
16  XXXXX                               0x00000001087300b8 108jVd8JFekR + 232
17  XXXXX                               0x000000010876ef40 100iZEfbT6gW + 1608
18  XXXXX                               0x000000010879297c 10QzlTW4v2Ir + 56
19  XXXXX                               0x0000000108775f10 10yEsmvqVxay + 320
20  XXXXX                               0x0000000108732e24 10mN8k4ha1CN + 496
21  XXXXX                               0x00000001086ff384 10444cFtXXLs + 148
22  libsystem_pthread.dylib             0x00000001c4e411ec _pthread_start + 124
23  libsystem_pthread.dylib             0x00000001c4e44aec thread_start + 8)

Observing the crash log at line 7 indicates that it's using ONIMethodId's method invokeWithTarget

After that I inspected symbols (command - nm frameworkBinary ) for all my 3rd party frameworks, I got to know one of my framework was using this method which was eventually calling _LSDefaults private method. And that method has been deleted from iOS >= 13.0 SDK.

I raised this to my 3rd party vendor and they'll provide an updated framework for the same.

Thanks to everyone for comments and watching the issue, posting the answer so that it can help anyone else facing the same issue in future.

unrecognized selector sent to instance-Swift

In target-action pattern, the target object needs to implement the action method.

But in your code:

self.callFuncTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.busInfoObject.downloadBusData(userId:warning:delegate:completed:)), userInfo: nil, repeats: true)

You use self as target, which is an instance of MapVC, that does not implement the method downloadBusData(userId:warning:delegate:completed:).

When you specify #selector(someInstance.methodName(...)) for the action method, you need to pass someInstance to the target object. In your case someInstance is self.busInfoObject.

Which means the line creating a Timer should become like this:

self.callFuncTimer = Timer.scheduledTimer(timeInterval: 5, target: self.busInfoObject, selector: #selector(self.busInfoObject.downloadBusData(userId:warning:delegate:completed:)), userInfo: nil, repeats: true)

But this does not work.


I was stupid enough that I have almost forgotten to tell you another important thing in target-action pattern.

Which is,

The signature of the action method is definitely fixed according to the target.

When using Timer, the signature needs to be the same as this:

class func scheduledTimer(timeInterval: TimeInterval, target: Any, selector: Selector, userInfo: Any?, repeats: Bool) -> Timer

- (void)timerFireMethod:(NSTimer *)timer

The notation is in Objective-C format, but the action method for Timer needs to have one and only one argument of type Timer (it's NSTimer in Objective-C.)

So, you may need to define a method matches the signature in your MapVC:

func timerFired(_ timer: Timer) {
self.busInfoObject.downloadBusData(userId: ...,
warning: {_, _, _ in
...
},
delegate: self,
completed: {
...
})
}

And change the line setting the timer to:

self.callFuncTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.timerFired(_:)), userInfo: nil, repeats: true)

Sorry, for showing you an incomplete answer, please try with filling ... in my updated code.

Unrecognized selector sent to class + uncaught exception of type NSException / NSInvalidArgumentException

Instead of MyViewController.self as the action target, use self:

let btnDone = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(onBtnDoneTap))

This means that the target is not the class MyViewController but a specific MyViewController instance.



Related Topics



Leave a reply



Submit