This question already has answers here:
What's the difference between a method and a selector?
(3 answers)
Closed 8 years ago.
Here I can't understand what is selector?, still now I knew it is used for calling methods,and someother says its is a callback mechanism.
What is the difference between these two methods.
Instance is created
Car *porsche = [[Car alloc] init];
The methods in these two ways whicih one is better.
SEL stepTwo = #selector(driveForDistance:);
[porsche performSelector:stepOne];
or
[porsche startEngine];
"whicih one is better" - neithier (sic) one is better. They have different purposes.
Furthermore, there aren't "normal" (or "abnormal", for that matter) methods. There are methods. And selectors are unique names identifying methods.
If you don't need dynamic method dispatch, then there's no reason for using performSelector: (even less reason to use it the wrong way you used it - calling a method that takes one argument without any arguments). If you know which method you want to call on an object, just call it.
If you need reflection and dynamism, then it's useful and reasonable to use selectors to dynamically resolve methods.
The performSelector allows you to dynamically determine which selector to call a selector on the given object. In other words the selector need not be determined before runtime.
Thus even though these are equivalent:
[theObject aMethod];
[theObject performSelector:#selector(theMethod)];
The second form allows you to do this:
SEL aSelector = findTheAppropriateSelectorForTheCurrentSituation();
[theObject performSelector: theSelector];
Short Answer :
Main thing performSelector allows you to dynamically determine which selector to call a selector on the given object and there is not need to determine it Runtime. But as Both are some In Perfromselector a Selector is the name of a method. message is a selector and the arguments you are sending with it. and where method is a combination of a selector and an implementation. Try this there are number of Question on SO.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Using -performSelector: vs. just calling the method
I can accomplish the same task in my application by doing:
[self performSelector:#selector(displayOneLife)];
and:
[self displayOneLife];
Is it better to use one or the other depending on the situation? If so, can someone elaborate for me? I would just like to use Objective-C best practices.
Thank you,
Joey
The -performSelector approach is usually used when you would like to invoke some selector not known at compilation time. For instance, UIButton uses it to invoke the action you wire it up to when a user hits it (the button knows the name of the method it is hooked up in IB and the class it it hooked up to).
For all other cases you should go with the latter as you don't want to convert your code into an unreadable puzzle.
P.S. -performSelector + dynamic selector name construction can be used to work around Apple's static analyzer which seeks the binary for prohibited invocations :)
You can store a selector in a variable, so performSelector: is useful for when you don't know at compile-time what message you want to send. For example, the target-action system is based on selectors. Here's a rudimentary implementation of a control:
#interface FakeControl : NSObject
#property(nonatomic, strong) id target;
#property(nonatomic, assign) SEL action;
- (void)click;
#end
#implementation FakeControl
- (void)click {
[target performSelector:action];
}
#end
By using a selector, we can have the control send any message we want at runtime when it's clicked.
#selector has a very specific use, and you should not use it to call known methods.
You use #selector to inform other classes of one of your methods that should be called.
For example you can pass the class countNumber a selector to your method #selector(result:) so that the other class will call your method when it has completed its task.
example code:
- (void)calculateANumber
{
[NumbersClass countNumber:myNumber withResult:#selector(result:)];
}
//This method will get called by NumbersClass, even tho it didnt know its existence before
- (void)result:(int)countResult
{
myResult = countResult;
}
Just an example, obviously, it does nothing
If you have to do some thing inline especially on the same thread
[self displayOneLife]
is good enough
But there are many instances, where you want to do the execution on another thread, or after a delay etc. If you just type, [self perform ...], you will see so many suggestions for methods available for performSelector, each of the method signatures will help you understand what it does.
Select one of the methods and just command click on the method name. It will show you details about what the method does etc.
It is a very good question but has many answers. Runloops, threads, delays, asynchronous operations are all reasons.
Referring to the discussion performSelector where is explained that with the following line it is possible to call a method
SEL aSelector = findTheAppropriateSelectorForTheCurrentSituation();
[anObject performSelector: aSelector];
My question is what is the content of the method called: findTheAppropriateSelectorForTheCurrentSituation()?
//For me the most important question
And another question is, why I get the warnings when using this piece of code.
1.warning: implicit declaration of function 'findTheAppropriateSelectorForTheCurrentSituation'
2.warning: initialization makes pointer from integer without a cast
3."_findTheAppropriateSelectorForTheCurrentSituation", referenced from:
Thank you for your answeres in advance
You'd have to look up the documentation or disassemble the binary that contains that method in order to determine exactly what it does. As for your warning, your syntax is incorrect. You should use the #selector(name) syntax in order to create a selector you can use to call [obj performSelector:].
I have a method called Display. Can somebody explain me the difference of calling the same method in the following two ways.
[self Display];
[self performselector:#selector(Display)]
- (void)Display {
NSlog(#"Data");
}
both are basically the same with one minute difference.. #selector gives a name to your method which you can pass around as an attribute to other objects or in other function calls.
Like if you want to send a message to other object and you want to send display as an attribute then you will have to give it a name using #selector and thus you can send it.. its a pretty vague concept.. hope this helps.
and to quote apple documents...
"However, the performSelector: method allows you to send messages that
aren’t determined until runtime. A variable selector can be passed as
the argument:
SEL myMethod = findTheAppropriateSelectorForTheCurrentSituation();
[anObject performSelector:myMethod];
The aSelector argument should identify a method that takes no
arguments. For methods that return anything other than an object, use
NSInvocation."
[self Display] is shorter and easier to read, write and comprehend.
[self performSelector:#selector(Display)] makes it possible to execute arbitrary selectors. If you save the selector in a variable, then you can execute it later on without knowing the method you invoke. It is therefore more flexible. Even better: you can pass selectors and objects to other objects and let them invoke it for you when necessary. An example why you want to use this is the NSUndoManager which simple invokes a selector to undo an action if the user executes the Undo command.
I do not think that there is a big difference between examples you provided, but perform selector is very useful when you for instance wanna move execution of your method to the background thread.
[self Display]; is a call to a known method on a known object.
It's easy to give it some params if your want : [self DisplayWithParam1:(NSString*)aString param2:(int)aNumber param3:(NSDictionary*)aDict
[self performselector:#selector(Display)] is a call that allows you to call a possibly not known method on a possibly not known object type.
Let's imagine you have many kind of classes that all respond to a given protocol that require to have the Display method implemented. You put some objects of thoses different classes in an NSMutableArray. When parsing the array later, you will get id typed objects.
So calling[myArrayObject Display]; will work at runtime but will generate a warning at compile time as id does not support any method of course, even if you know that this object supports the method.
To prevent thoses warning, call [myArrayObject performselector:#selector(Display)];.
The problem with that call is that is harder to pass some parameters.
performSelector:withObject:withObject:
Sends a message to the receiver with two objects as arguments.
- (id)performSelector:(SEL)aSelector withObject:(id)anObject withObject:(id)anotherObject
Parameters
aSelector
A selector identifying the message to send. If aSelector is NULL, an NSInvalidArgumentException is raised.
anObject
An object that is the first argument of the message.
anotherObject
An object that is the second argument of the message
Return Value
An object that is the result of the message.
Discussion
This method is the same as performSelector: except that you can supply two arguments for aSelector. aSelector should identify a method that can take two arguments of type id. For methods with other argument types and return values, use NSInvocation.
Availability
Available in Mac OS X v10.0 and later.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocSelectors.html
The #select call is faster. Generally the uglier (and less dynamic) the code you have in Objective-C, the faster it runs. Here, the selector call bypasses the usual call to objc_msgSend().
I wouldn't recommend writing code like this if you can avoid it. Selectors are somewhat common in Cocoa, but if you're using it for a speedup it's really not worth it. objc_msgSend() is highly optimized and very fast.
I'm trying to transform one method call into another dynamically (at runtime).
For instance, I'd like the following:
[obj foo]
to delegate to:
[obj getAttribute: #"foo"]
(I'd like to do this dynamically as I don't know ahead of time what those method names or attributes are going to be).
I see that there's a hook into:
- (id) forwardingTargetForSelector: (SEL) aSelector
That only seems to work for delegation, though, I want to keep the object as "self" and transform the method arguments.
Where should I look for this sort of behavior? Is it even possible in obj-c?
You can use the method -forwardInvocation: for that. It takes a full NSInvocation object which represents the method call, and you can handle it however you wish. If you do this, you should also override -methodSignatureForSelector: to return the correct NSMethodSignature (required for -forwardInvocation: to work on unknown selectors). It's also recommended that you override -respondsToSelector: to declare that you can handle the selector in question.
I want to add a selector into a dictionary (the main purpose is for identifying the callback method and delegate after finish doing something)
But I find that I can not do that, the program will get an error "EXC_BAD_ACCESS".
Are there any other way for me to add that method selector to a dictionary?
Thanks for your help.
I know this question was answered a long time ago, but just in case anyone stumbles upon it like I did...
The combination of NSStringFromSelector and NSSelectorFromString as answered above is probably the best way to go. But if you really want to, you can use a selector as a value or key in an NSDictionary.
A selector (type SEL) is implemented as a pointer to a struct in Apple's Objective-C runtimes. A pointer cannot be used directly in a dictionary, but a pointer can be wrapped in an NSValue object that can be used.
Using this method you can store a selector as a value in a dictionary using code like this:
dictionary =
[NSDictionary dictionaryWithObject:[NSValue valueWithPointer:selector]
forKey:key];
A selector can be retrieved using code like this:
SEL selector = [[dictionary objectForKey:key] pointerValue];
Similarly for using a selector as a key:
dictionary =
[NSDictionary dictionaryWithObject:value
forKey:[NSValue valueWithPointer:selector]];
value = [dictionary objectForKey:[NSValue valueWithPointer:selector]];
Adding a new entry to a dictionary does two things (in addition to adding it to the dictionary, obviously):
It takes a copy of the key value. This means that the the key object must implement the NSCopying protocol
retains the value. This means that it needs to implement the NSObject protocol
It's probably the second that's causing your EXC_BAD_ACCESS.
There are at least two ways around this.
Firstly, rather than adding the selector you could add the instance of the class that implements the selector to your dictionary. Usually your class will inherit from NSObject and it will work fine. Note that it will retain the class though, maybe not what you want.
Secondly, you can convert a selector to a string (and back again) using NSSelectorFromString and NSStringFromSelector (docs are here).
I get my answer based on the comment of Zydeco:
You can convert between SEL and
NSString using NSSelectorFromString
and NSStringFromSelector
The common idiom in Obj-C is to have specific names for callbacks for specific events. (Such parserDidBeginDocument: from NSXMLParserDelegate). If you really need to be able to specify the names, it is likely that your only recourse is to add the names of the selectors as #"mySelector:withArgument:context:" or somesuch.