2012-02-08 7 views
5

एक आईओएस ऐप में, मैं UIWebView पर stringByEvaluatingJavaScriptFromString (जावास्क्रिप्ट स्ट्रिंग की लंबाई के मामले में बड़े) का उपयोग करके काफी बड़ी लिपि चला रहा हूं। स्क्रीन पर अन्य तत्वों को एक पल के लिए हिचकी करने के लिए जावास्क्रिप्ट को कॉल करने के बाद एक संक्षिप्त विराम है।UIWebView stringByEvaluatingJavaScriptFromString पृष्ठभूमि में

self performSelectorInBackground के साथ पृष्ठभूमि में नामक फ़ंक्शन में जावास्क्रिप्ट कॉल रखने से एप्लिकेशन को तोड़ दिया जाता है। पृष्ठभूमि थ्रेड पर इसे चलाने के लिए कोई सुरक्षित तरीका है या अन्यथा इंटरफ़ेस को रोकने से रोकें?

उत्तर

0

आप उस कॉल को NSOperation में डालने का प्रयास कर सकते हैं। चूंकि आप यूआई तत्व के साथ काम कर रहे हैं, इसलिए [NSOperationQueue mainQueue] का उपयोग करना सुनिश्चित करें।

+0

यह कैसे मदद करेगा? –

2

UIWebView के साथ आप जो कुछ भी करते हैं वह मुख्य धागे पर किया जाना चाहिए। यह एक यूआई तत्व है, इसलिए performSelectorInBackground आपके ऐप को तोड़ देता है।

3

नहीं, वेबव्यू और वेबकिट जावास्क्रिप्ट इंजन दोनों एकल-थ्रेडेड हैं और पृष्ठभूमि थ्रेड पर उपयोग नहीं किए जा सकते हैं।

एक बेहतर विकल्प असतत निष्पादन ब्लॉक और उन्हें पाइप लाइन एक जावास्क्रिप्ट टाइमर (, नहीं Obj सी जे एस कोड) का उपयोग कर, इस तरह में अपने जावास्क्रिप्ट को विभाजित करने के लिए है:

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(); 

यही से अपनी स्क्रिप्ट पाएगा उपयोगकर्ता इंटरैक्शन को अवरुद्ध करते हुए

+0

धन्यवाद। यह आधा समस्या हल करता है और आवश्यक से भी थोड़ा अधिक है। बस उस फ़ंक्शन को कॉल करना जो एक संक्षिप्त टाइमर के साथ सभी काम करता है, पॉज़ को बहुत छोटा बनाता है। यदि मैं इस अधिकार को समझता हूं, तो एक बार 'stringByEvaluatingJavaScriptFromString' फ़ंक्शन में स्क्रिप्ट निष्पादित हो जाती है, मुख्य थ्रेड जारी रख सकता है, इसलिए जेएस टाइमर द्वारा बुलाया जाने वाला फ़ंक्शन स्वतंत्र रूप से चलाने की अनुमति है। अभी भी एक बड़ी स्ट्रिंग के साथ 'stringByEvaluatingJavaScriptFromString' को कॉल करने से थोड़ा सा विराम है। शायद ओबीजे-सी पक्ष पर इस दृष्टिकोण की तरह कुछ उस को कम कर सकता है। –

+0

एक स्ट्रिंग के रूप में पूरी स्क्रिप्ट को पारित करने के बजाय, आप इसे अपने पृष्ठ के लिए एचटीएमएल में एक स्क्रिप्ट टैग के रूप में जोड़ सकते हैं और फिर स्ट्रिंगबैवलुएटिंग जावास्क्रिप्टफ्रेमस्ट्रिंग के साथ फ़ंक्शन को कॉल करके इसे ट्रिगर कर सकते हैं। –

+0

ऐसा लगता है कि एक ही सुधार है, लेकिन फिर भी 100% नहीं है। –

3

ठीक है, मैं वही कर रहा था। मुझे एक सिंक्रोनस AJAX अनुरोध चलाया गया था जो मेरे यूआई को ठंडा कर रहा था। तो इस तरह मैंने इसे ठीक किया:

__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]; 
     }); 
    }); 

तर्क सरल है। एक नए धागे पर जाएं, और उसके भीतर से, मुख्य कतार में प्रेषण करें और फिर जेएस काम करें और सबकुछ मेरे लिए आकर्षण की तरह काम करता है ...