Senči
Senči

Reputation: 941

Is it possible to "pause" a thread and let another operation proceed first?

I set up 2 UIWebViews, the first is controlling the second. They are communicating though ajax requests.

I want to load a website in the second WebView and then proceed with other tasks. Unfortunately this is crashing. It is crashing because the Web Thread is being occupied by the first right after it gets a response. The second has no time to load the web page and causes a deadlock.

I want to delay the response until the second WebView has fully loaded the web page. Currently the second WebView starts loading right after the first WebView gets and response (thats when the Web Thread is being released).

Is it possible to "suspend"/"pause" the current (first WebView) execution until the second WebView has finished loading? This means to start the execution of the second WebView as well.

events:

  1. First WebView sends command to load web page (using synchronous AJAX command)
  2. Web Thread blocked by task of first WebView
  3. Execution of command and computation of Response
  4. Returning Response
  5. Second WebView starts Loading of web page
  6. deadlock

I want event 5 to be before event 4. Is this possible?

Solution: As you can read in the comments I've solved my problem by making then work concurrently. Basically I had to make use of the Grand Central Dispatch (GCD). Another option would be to implement it with NSOperationQueues which gives you more control about the flow of execution, but tends to be more complicated to implement.

helpful literature:

Upvotes: 2

Views: 915

Answers (3)

JonahGabriel
JonahGabriel

Reputation: 3104

Now, this is may require some tweaking, but it should give you a good place to start.

Basically, we create a concurrent GCD queue and dispatch 2 async calls to load HTML strings with the contents of your 2 different URLS.

When the requests complete they will load their html strings into your web views. Note that the first UIWebView will only load its data if the second UIWebView has already been loaded.

 __weak ViewController *bSelf = self;
dispatch_queue_t webQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(webQueue, ^{
    NSError *error;
    bSelf.html1 = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://google.com"] encoding:NSASCIIStringEncoding error:&error];
    if( !bSelf.secondLoaded)
    {
        dispatch_sync(dispatch_get_main_queue(), ^{
            [bSelf.webView1 loadHTMLString:bSelf.html1 baseURL:nil];
        });
    }
});

dispatch_async(webQueue, ^{
    NSError *error;
    bSelf.html2 = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://amazon.com"] encoding:NSASCIIStringEncoding error:&error];
    bSelf.secondLoaded = YES;
    dispatch_sync(dispatch_get_main_queue(), ^{
        [bSelf.webView2 loadHTMLString:bSelf.html2 baseURL:nil];
        if( bSelf.html1 != nil )
        {
            [bSelf.webView1 loadHTMLString:bSelf.html1 baseURL:nil];
        }
    });

});

Upvotes: 4

Mike Z
Mike Z

Reputation: 4111

Yes, the two best ways to do this would be to use either Grand Central Dispatching (GCD) or NSOperation and NSOperationQueue.

The explanation of this is quite long, but I would direct you to read something like this. You can find a lot of other resources if you search for these terms in google.

Upvotes: 2

klcjr89
klcjr89

Reputation: 5902

Have you tried something like this?

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.webView.delegate = self;
    self.webView2.delegate = self;

    [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"yourURL"]]];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    if (webView == self.webView)
    {
        if (!self.webView.isLoading)
        {
            [self.webView2 loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"yourURL"]]];
        }
    }
}

Upvotes: 0

Related Questions