Swift alternative to respondsToSelector:
You have two ?
operators, and they're both causing problems.
First, the one after delegate
indicates that you want to unwrap an optional value, but your delegate
property isn't declared that way. It should be:
var delegate: CustomItemTableViewCellDelegate?
Second, it looks like you want your changeCount
protocol method to be optional. If you do, you need to both mark the protocol with the @objc
attribute and mark the function with the optional
attribute:
@objc protocol CustomItemTableViewCellDelegate {
optional func changeCount(sender: UITableViewCell, change: Int)
}
(Note: Classes that conform to @objc
protocols need to be @objc
themselves. In this case you're subclassing an Objective-C class, so you're covered, but a new class would need to be marked with the @objc
attribute.)
If you only want the delegate to be optional (that is, it's okay to not have a delegate, but all delegates need to implement changeCount
), then leave your protocol as is and change that method call to:
delegate?.changeCount(self, change: -1)
What is the Swift equivalent of respondsToSelector?
As mentioned, in Swift most of the time you can achieve what you need with the ?
optional unwrapper operator. This allows you to call a method on an object if and only if the object exists (not nil
) and the method is implemented.
In the case where you still need respondsToSelector:
, it is still there as part of the NSObject
protocol.
If you are calling respondsToSelector:
on an Obj-C type in Swift, then it works the same as you would expect. If you are using it on your own Swift class, you will need to ensure your class derives from NSObject
.
Here's an example of a Swift class that you can check if it responds to a selector:
class Worker : NSObject
{
func work() { }
func eat(food: AnyObject) { }
func sleep(hours: Int, minutes: Int) { }
}
let worker = Worker()
let canWork = worker.respondsToSelector(Selector("work")) // true
let canEat = worker.respondsToSelector(Selector("eat:")) // true
let canSleep = worker.respondsToSelector(Selector("sleep:minutes:")) // true
let canQuit = worker.respondsToSelector(Selector("quit")) // false
It is important that you do not leave out the parameter names. In this example, Selector("sleep::")
is not the same as Selector("sleep:minutes:")
.
respondsToSelector on optional delegate methods
Swift supports optionals for methods as well.
You can do this instead:
graduationColor = delegate.analogClock?(self, graduationColorForIndex: i) ?? UIColor.whiteColor()
Or the long way:
if let graduationColor = delegate.analogClock?(self, graduationColorForIndex: i) {
self.graduationColor = graduationColor
} else {
self.graduationColor = UIColor.whiteColor()
}
Swift4: respondstoSelector not working
You need to add @objcMembers at top of observer
class
For Ex. if observer
is a object of XYZClass
class then write
@objcMembers
class XYZClass : NSObject
{
// Your Stuff
}
OR
Another way is to put @objc
to start of your method like below.
@objc func managerDidDetectedStation...
What is the swift equivalent to setting properties on `id`?
In Swift 2.0 beta 4, your prayers are answered; this code becomes legal:
@IBAction
func handleEvent(sender: AnyObject) {
if sender.respondsToSelector("setHidden:") {
sender.performSelector("setHidden:", withObject: true)
}
}
self.delegate respondsToSelector: ... does not compile
-respondsToSelector:
is a method on NSObject. Either assume that your id
delegate is in fact an NSObject, and cast it:
[(NSObject*)self.delegate respondsToSelector:@selector(myClass:willDoSomething:)]
Or, better, make your delegate explicitly an NSObject:
@property (nonatomic, weak) NSObject<MyClassDelegate>* delegate;
Or make the protocol be a sub-protocol of NSObject:
@protocol MyClassDelegate <NSObject>
Objective C - respondsToSelector for dynamic properties
[[MyObject class] respondsToSelector:...]
asks whether the metaobject responds to that selector. So, in effect, it asks whether there is a class method with that selector. Your code would return YES if you had:
+ (NSString *)myProperty;
It returns NO because you have the equivalent of the instance method:
- (NSString *)myProperty;
You need to call respondsToSelector:
on an instance of your class.
You could normally use instancesRespondToSelector:
directly on the metaclass (so, [MyObject instancesRespondToSelector:...]
) but Core Data synthesises the relevant method implementations only when you create an object, so that's a non-starter. You could however create an instance via the normal NSEntityDescription
route and test respondsToSelector:
on that.
Since it's all Core Data, an alternative would be to ask the NSManagedObjectModel
for the relevant NSEntityDescription
via its entitiesByName
dictionary and inspect the entity description's propertiesByName
dictionary.
Related Topics
Ckcontainer.Discoverallidentities Always Fails
How to Observe Array Property Changes in Rxswift
How to Draw Line Node Keep Same Size in Camera as Measure App in Iphone
"Use Default Container" Doesn't Show in Icloud Capabilities
Different Colors for Bars in Barchart Depend on Value
How to Make Embedded View Controller Part of the Responder Chain
Swift - How to Get Text Formatting in a Text Editor Like in the Notes App? Swiftui
Using a Metal Shader in Scenekit
Non Exhaustive List When Handling Errors Inside a Class Function in Swift
What Is the Markup Format for Documentation on the Parameters of a Block in Swift
Swift Memory Management: Storing Func in Var
Firebase Auth Internal Error on Login Attempt
Swift 3/Macos: Open Window on Certain Screen
Typealias of Generic Class in Swift
How to Do a Long Press in Swift