Malek_Jundi
Malek_Jundi

Reputation: 6160

Invoke non void functions with performSelectorOnMainThread

As the title of my question said .. I'm try to call a non-void function with performSelectorOnMainThread .. my function return UIImage , when I call it like this:

UImage *img = [self performSelectorOnMainThread:@selector(captureScreen:) withObject:webView waitUntilDone:YES];

it gives me an error that I have incompatible assigning type , also I try to cast it like this

UImage *img = (UIImage*)[self performSelectorOnMainThread:@selector(captureScreen:) withObject:webView waitUntilDone:YES];

and I got Semantic Issue: Operand of type 'void' where arithmetic or pointer type is required

I know that I can call it as normal , but Im trying some multithreading stuff and need it to invoke like this .. so how I can prevent this error please?

Edit :

I try to use GCD inside this function (captureScreen) its keep making Exc_bad_access on the "viewToCapture" .. so I decide to call the parent function inside the GCD block

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

dispatch_async(queue, ^{
    [self captureScreenDelayed:pageView];

    dispatch_sync(dispatch_get_main_queue(), ^{
    });
});

and "captureScreenDelayed:" is as follow

- (void) captureScreenDelayed:(EpubPageViewController*)pageView
{
    if(!pageView)
        pageView = [self currentPageView];

    if(pageView.pageImageView)
        pageView.pageImageView.image = (UIImage*)[self performSelectorOnMainThread:@selector(captureScreen:) withObject:webView waitUntilDone:YES];
}

and the captureScreen :

-(UIImage*)captureScreen:(UIView*) viewToCapture
{

    UIGraphicsBeginImageContextWithOptions(viewToCapture.bounds.size, viewToCapture.opaque, 0.0);
    [viewToCapture.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return viewImage;
}

to be honest Im not sure if this the correct way to get the image in separated thread... I appreciate any advice.

Upvotes: 4

Views: 1597

Answers (2)

Sean
Sean

Reputation: 5820

The thing you have to remember here is that the method that you're actually calling is -performSelectorOnMainThread:withObject:waitUntilDone: which has a (void) return type. Thus, you can't get the result of the performed selector returned through this method. If you need to do this type of multithreading, you should check out the concurrency programming guide and, in particular, grand central dispatch.

Upvotes: 4

JeremyP
JeremyP

Reputation: 86651

performSelectorOnMainThread:... does not have a return value. You'll need to find some other mechanism to get the image back. One simple way, that will work in this case because you are waiting for the selector to complete, would be to pass an NSMutableArray as your object and add the image to it in the main thread e.g.

NSMutableArray* parameterArray = [[NSMutableArray alloc] init];
[parameterArray addObject: webView];
[self performSelectorOnMainThread:@selector(captureScreen:) withObject:parameterArray waitUntilDone:YES];
if ([parameterArray count > 1)
{
    UIImage* img = [webView objectAtIndex: 1];
}
else
{ 
// error
}

And captureScreen: would look something like

-(void) captureScreen: (NSMutableArray*) parameterArray
{
    UIView* webView = [parameterArray objectAtIndex: 0];
    // capture the screen
    [parameterArray addObject: capturedImage];
}

Upvotes: 4

Related Questions