When you retrieve the ID of a selector with @selector(), is the selector value different depending on the types of the arguments?
Here’s what I mean. I have a method that takes an object reference and a selector, then calls it with a parameter:
-(void)CallLater:(NSObject*) Obj Sel: (SEL)Sel
{
//Some stuff, then:
[Obj performSelector: Sel withObject: SomeOtherObject];
}
I’m using this method with a selector to a function that takes a typed object reference, not an id:
-(void)MyMethod: (MyObject*) a
{
}
[self CallLater: self Sel:@selector(MyMethod:)];
It seems to work, but my senses are tingling. In a statically typed language like C# this would be a foul, an upcast – CallLater is expecting a selector for a function that takes an id and I’m giving it a function that takes a MyObject.
On the other hand, the compiler does not complain, and both id and concrete object references seems to be mere pointers deep down, trivially castable to one another. Then again, there are many fouls that Objective C compiler does not complain about.
So the real question is – is it safe? Language lawyers welcome.
It’s safe; objects are objects. A selector parameter for an
NSObject *is exactly the same as a selector parameter for aMyObject *.If you want MyMethod to verify that it’s being called with an object of a particular type, it should do a NSParameterAssert on it:
Personally, I rarely do this check. It’s enough that the actual object acts like the type I want it to be, and if it doesn’t I’ll get a runtime error (usually unrecognized selector). You’ll get a compiler warning in the simple cases, and it’s worth paying attention to this warning (and silencing it with an id cast when necessary).
I’m a bit confused here about your use of
idin your question, so I want to make sure you understand this: AnNSObject *is exactly as much anidas aMyObject *is.idis a generic instance pointer class, whereasNSObject *is aNSObjectinstance (or a subclass ofNSObject). You can have objects that don’t descend fromNSObject. But you’re unlikely to ever have to know this.Other notes, re: convention:
CallLater:Sel:should becallLater:sel:.Objabove should beobj.