Reputation: 5976
For example I have a method that looks like this
[self performSelectorOnMainThread:@selector(someMethod)
withObject:data
waitUntilDone:YES];
In which "someMethod" is from another class. If it is possible, how can I do that? Also, I'd like to know how can I pass in the parameters.
Assume that someMethod is defined as:
- (void)someMethod:(NSData *)data otherArg:(NSString *)arg;
Upvotes: 1
Views: 1758
Reputation: 385610
The message you want to send takes two parameters, and there's no variant of performSelectorOnMainThread:...
that passes two parameters with the message.
The easiest way to do this is to use Grand Central Dispatch and a block. If you are sure that you will not do this on the main thread, you can do this:
dispatch_sync(dispatch_get_main_queue(), ^{
[otherObject someMethod:myData otherArg:@"my argument"];
});
But if you run that code when you're already on the main thread, that code will deadlock - your app will hang.
If you might want to do it when you're already on the main thread, you have to be more careful to avoid deadlock. I'd do it like this:
dispatch_block_t block = ^{
[otherObject someMethod:myData otherArg:@"my argument"];
};
if (dispatch_get_current_queue() == dispatch_get_main_queue()) {
block();
} else {
dispatch_sync(dispatch_get_main_queue(), block);
}
Upvotes: 0
Reputation: 124997
It depends. If 'self' inherits from the class that implements someMethod
, then you can of course do that. But you can't send a message to an object whose class (or ancestor class) doesn't implement that method. (Well, you can, but expect an error.)
The code snippet you show is similar to:
[self someMethod:data];
except that someMethod:
will run on the main thread rather than whatever thread is currently executing. Looking at it that way may help you remember that the receiver (self
in this case, but it could be a pointer to any object) has to implement the message you're sending.
Upvotes: 1
Reputation: 11839
Yes you can call selector of another class as well.
If selector is class method -
[ClassName performSelectorOnMainThread:@selector(someMethod:)
withObject:data
waitUntilDone:YES];
and method signature is something like -
+ (void)someMethod:(returntype)somearg
If selector is instance method -
[classInstance performSelectorOnMainThread:@selector(someMethod:)
withObject:data
waitUntilDone:YES];
and method signature is something like -
- (void)someMethod:(returntype)somearg
Upvotes: 3
Reputation: 9392
Instead of self, you replace that with the instance of the class you want to perform the selector on.
Upvotes: 0
Reputation: 33421
You need to replace self
with an instance of the class that defines the method. Otherwise you will get an unrecognized selector error. Also, don't forget to put a colon ( :
) after someMethod
if you are sending it an argument.
Upvotes: 3