ObjC: cast of an indirect pointer to an Objective-

2019-08-20 07:59发布

问题:

How can I change the following code to be compatible with ARC:

MyObj* fn = nil;
[self performSelectorOnMainThread:@selector(popSomething:) withObject:(id)&fn waitUntilDone:YES];

Right now, I get the following error:

error: cast of an indirect pointer to an Objective-C pointer to '__strong id' is disallowed with ARC [4]

回答1:

The type of the argument should be (id *), ie. a pointer to an object, not an object.

But if you just want to return a value from a method that you need to execute on the main thread, a nicer solution is to use blocks and GCD:

__block id poppedFilename;
dispatch_sync(dispatch_get_main_queue(), ^{
     poppedFilename = [self popFilename];
});
// do something with the popped file

This executes the method -popFilename on the main thread, and stores the result in poppedFilename. You must be careful not to call this method on the main thread, as it would deadlock. If you aren't sure if you are on the main thread, you could use something like this:

__block id poppedFilename;
if ([NSThread isMainThread]) {
     poppedFilename = [self popFilename];
} else {
     dispatch_sync(dispatch_get_main_queue(), ^{
         poppedFilename = [self popFilename];
     });
}


回答2:

If you're expecting the main thread to update the string, then a better way to do it would be to use a mutable string and simply pass it to the main thread:

NSMutableString* fn = [NSMutableString string];
[self performSelectorOnMainThread:@selector(queuedFileNamesPop:) withObject:fn waitUntilDone:YES];

Then the main thread can simply update the string.