Esqarrouth
Esqarrouth

Reputation: 39181

When to use respondsToSelector vs objc_getClass

if respondsToSelector("UIAlertController"){
    //do something
}

if objc_getClass("UIAlertController") != nil{
    //do something
}

These both have the same results overall. Is there a case when one is better than the other one? Or should only one of them be used and the other forgotten?

Upvotes: 1

Views: 958

Answers (3)

Jasper Blues
Jasper Blues

Reputation: 28746

These two methods do not have the same result overall.

Responds to Selector

The first case respondsToSelector is a part of the NSObject protocol and will simply indicate if an object is capable of responding to a message with the given signature, at the time of calling. It can be used for a number of cases:

  • Polymorphism. Ie, informal protocols, or particularly in conjunction with conformsToProtocol for checking if an instance (of any class) responds to the part of a protocol under the @optional directive.
  • For deciding whether to forward a message to another target.
  • For instrumenting an object with additional functionality at runtime, for example putting transaction/rollback capability on a persistent model object.
  • In publish/subscribe type scenarios.

Get Class

The second method is a low-level member of the Objective-C runtime. It is used to simply check the kind of class an object is presenting itself as. (It will check the isa pointer). There are methods on the NSObject protocol that can do the same thing, and it would be generally recommended to use these, unless you have a specific reason to fall back to the lower level APIs. These methods are [an instance class] and [anInstance isKindOfClass].

Replace instanceof with Polymorphism

While there are a great deal of valid uses for querying an object's class, in a typical application it is often a design flaw. There's a refactoring pattern called "replace instanceof with polymorphism". By that we mean, instead of asking an object what kind of class it is, then doing something, instead specific based on that, instead create a protocol and have each of the possible classes implement the method of that protocol in their specific way. Example:

if ([foo isKindOfClass:[Holiday class]]) {
    //evaluate if approved
} else if ([foo isKindOfClass:[SickLeave class]]) {
    //evaluate if approved
}

Instead do . .

id<Leave> leave;
[leave approveOrDecline]

Upvotes: 1

Midhun MP
Midhun MP

Reputation: 107121

For checking the class existence you must use objc_getClass. (For Class compatibility with iOS versions)

For checking whether a class implemented a method or a method is available or not you need to use respondsToSelector (For method availability with versions)

Upvotes: 1

Mrunal
Mrunal

Reputation: 14118

respondsToSelector : This is basically used for to check if object reference, can call perticular method or not. For example, object has inherited from some base class or implemented by some protocols, then it is better to check whether object is able to respond to that method or not, then only call it.

Otherwise it will throw runtime error, method not found type.

if([obj respondsToSelector:@selector(anyMethod)]) {
   [obj fizzyWizzle];
}
else {
   // do something
}

objc_getClass : The Class object for the named class, or nil if the class is not registered with the Objective-C runtime. It means, are you able to access this class or not, if that class does not exist then it will return 'nil'. So,

if objc_getClass("UIAlertController") != nil{
    // it means, these class is available in SDK, hence its iOS version is 8.x
    // here you can alloc - init and use UIAlertController functionality
}
else {
   // class could not be found
   // iOS version is < 8.0
   // here that class is not available hence use UIAlertView which is supported by iOS 7 and earlier.
}

Hope this helps.

Upvotes: 2

Related Questions