2012-02-08 27 views
5

Trong ứng dụng iOS, tôi đang chạy một tập lệnh khá lớn trên UIWebView sử dụng stringByEvaluatingJavaScriptFromString (lớn về độ dài của chuỗi javascript). Có một tạm dừng ngắn sau khi gọi javascript gây ra các yếu tố khác trên màn hình để nấc cục trong giây lát.UIWebView stringByEvaluatingJavaScriptFromString trong nền

Đặt cuộc gọi javascript trong một chức năng được gọi là ở chế độ nền với self performSelectorInBackground vi phạm ứng dụng. Có cách nào an toàn để gọi chạy điều này trên một sợi nền hoặc ngăn cản giao diện tạm dừng?

Trả lời

0

Bạn có thể thử thực hiện cuộc gọi đó thành NSOperation. Vì bạn đang làm việc với một phần tử giao diện người dùng, hãy đảm bảo sử dụng [NSOperationQueue mainQueue].

+0

Điều đó sẽ giúp ích gì? –

2

Mọi thứ bạn làm với số UIWebView phải được thực hiện trên chuỗi chính. Đó là một phần tử giao diện người dùng, vì vậy đây là lý do tại sao performSelectorInBackground phá vỡ ứng dụng của bạn.

3

Không, các bản xem trước web và công cụ JavaScript Webkit đều đơn luồng và không thể được sử dụng trên một chuỗi nền.

Một lựa chọn tốt hơn là để chia tay JavaScript thành các khối thực hiện rời rạc và đường ống dẫn họ sử dụng một bộ đếm thời gian JavaScript, như thế này (mã JS, không obj-C):

var i = 0; 
var operation = function() { 

    switch (i) { 
    case 0: 
     //do first part of code 
     break; 
    case 1: 
     //do second part of code 
     break; 
    case 2: 
     //do third part of code 
     break; 
    etc... 
    } 

    //prepare to execute next block 
    i++; 
    if (i < TOTAL_PARTS) { 
     setTimeout(operation, 0); 
    } 
}; 
operation(); 

Điều đó sẽ ngăn chặn kịch bản của bạn từ chặn tương tác người dùng trong khi thực thi

+0

Cảm ơn. Điều này giải quyết một nửa vấn đề và thậm chí còn nhiều hơn một chút là cần thiết. Đơn giản chỉ cần gọi chức năng mà tất cả các công việc với một bộ đếm thời gian ngắn làm cho tạm dừng ngắn hơn nhiều. Nếu tôi hiểu điều này đúng, một khi kịch bản trong hàm 'stringByEvaluatingJavaScriptFromString' thực thi chuỗi chính có thể tiếp tục, do đó hàm được gọi bởi bộ đếm thời gian js được phép chạy độc lập. Vẫn còn một chút tạm dừng khi gọi 'stringByEvaluatingJavaScriptFromString' bằng một chuỗi lớn. Có lẽ một cái gì đó như cách tiếp cận này ở phía obj-c có thể làm giảm bớt điều đó. –

+0

Thay vì truyền toàn bộ tập lệnh dưới dạng chuỗi, bạn có thể thêm nó dưới dạng thẻ tập lệnh vào html cho trang của bạn và sau đó chỉ kích hoạt nó bằng cách gọi hàm bằng stringByEvaluatingJavaScriptFromString. –

+0

Điều đó dường như có cùng sự cải thiện, nhưng vẫn không 100%. –

3

Vâng, tôi đã làm điều tương tự. Tôi đã phải chạy một yêu cầu ajax đồng bộ đã đóng băng giao diện người dùng của tôi. Vì vậy, đây là cách tôi đã khắc phục sự cố:

__block NSString *message; 
    dispatch_queue_t q = dispatch_queue_create("sign up Q", NULL); 
    dispatch_async(q, ^{ 
     NSString *function = [[NSString alloc] initWithFormat: @"signup(\'%@\',\'%@\',\'%@\')",self.email.text,self.password.text,self.name.text]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      NSString *result = [self.webView stringByEvaluatingJavaScriptFromString:function]; 
      NSLog(@"%@",result); 

      if ([result isEqualToString:@"1"]) { 
       message = [NSString stringWithFormat:@"Welcome %@",self.name.text]; 
       [self.activityIndicator stopAnimating]; 
       [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 
      } 

      else { 
       message = [NSString stringWithFormat:@"%@ is a registered user",self.name.text]; 
       [self.activityIndicator stopAnimating]; 
       [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 
      } 

      UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Message" message:message delegate:self cancelButtonTitle:@"Okay" otherButtonTitles: nil]; 
      [alertView show]; 
     }); 
    }); 

Logic đơn giản. Đi đến một chủ đề mới, và từ bên trong đó, gửi đến hàng đợi chính và sau đó thực hiện công việc JS và mọi thứ hoạt động như một sự quyến rũ cho tôi ...

Các vấn đề liên quan