Syntax for respondsToSelector:selector

(Phil Stokes) #1

I have a script which at one point iterates over an NSArray of objects. I’m only interested in those that are NSDictionary, so my initial thought was to try

if (obj's isKindOfClass:(NSDictionary's class)) then

Alas, although that worked with other classes (e.g., NSData), it seems that the objects ( NSCFDictionary’s underneath) return false for that. Why is a mystery to me.

It then occurred to me to try seeing whether the class responds to “objectForKey” (which is actually what I’m calling on the next line of the script).

So I came up with

if (obj's class's respondsToSelector:"objectForKey:") then
				-- do something
				end if

Alas, that never returns true either, so I’m wondering if I’ve got the syntax muddled up.

A couple of FWIWs:

  1. in this array there’s 40 some objects, 34 or so of them are NSDictionary/NSCFDictionary, the others are either NSString, NSData or NSNumber. I suppose I could use a bunch of is not conditionals, but that seems both fragile and inefficient.
  2. If I just leave out the condition and go straight to the next line and call ‘objectForKey’ on the object (regardless of what class it is), the script does in fact succeed; AppleScript seems to ignore the underlying unrecognized selector sent to instance error messages (possibly cos the repeat is wrapped in a try block); however, I’d like to produce something more robust that doesn’t just trample over the errors, but takes steps to avoid them.

TIA for any thoughts! :slight_smile:

(Phil Stokes) #2

Ah. Rubber duck moment. As soon as I read that back I realised the answer.

objectForKey is an instance method, not a class method. So

if (obj's respondsToSelector:"objectForKey:") then

works fine!

(Shane Stanley) #3

I wonder if using class instead of |class|() has something to do with it. FWIW, I find it works to leave off the class part anyway:

   if (obj's isKindOfClass:(current application's NSDictionary)) as boolean then

(Phil Stokes) #4

I didn’t know you could do that, actually. Thx Shane. :slight_smile:

(Thomas Tempelmann) #5

I am surprised you do not have to convert the string into a @selector object with NSSelectorFromString(), as one would have to do in plain C. I assume the ObjC-AS bridge automatically takes care of that?

(Shane Stanley) #6

Yes, you provide selectors as strings and the bridge does the conversion, and vice-versa. In fact, if you run this script:

use framework "Foundation"
set x to current application's NSSelectorFromString("compare:")

You will see the result is a string (not even an NSString) anyhow.