2013-10-14 7 views
9

निष्पादित नहीं कर रहा है, मैं अपने स्थानीय नोड सर्वर से कुछ डेटा खींचने की कोशिश कर रहा हूं। सर्वर को अनुरोध प्राप्त हो रहा है और इसे लॉगिंग कर रहा है, लेकिन किसी कारण से मेरा आईओएस ऐप पूरा होने वाले हैंडलर में मौजूद किसी भी कोड को निष्पादित नहीं करेगा।NSURLSessionDataTask पूर्णता हैंडलर ब्लॉक

- (IBAction) buttonPressed{ 
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:3000/"]; 
NSURLSessionDataTask *dataTask = 
[self.session dataTaskWithURL:url 
      completionHandler:^(NSData *data, 
           NSURLResponse *response, 
           NSError *error){ 
       nameLabel.text = @"yay!"; 
       /* 
       if (!error){ 
        nameLabel.text = @"noerr"; 
        NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response; 
        if (httpResp.statusCode == 200){ 
         NSError *jsonErr; 

         NSDictionary *usersJSON = 
         [NSJSONSerialization JSONObjectWithData:data 
                 options:NSJSONReadingAllowFragments 
                 error:&jsonErr]; 

         if (!jsonErr){ 
         // nameLabel.text = usersJSON[@"username"]; 
          nameLabel.text = @"nojerr"; 

         } 
         else{ 
          nameLabel.text = @"jsonErr"; 
         } 
        } 
       } 
       else{ 
        nameLabel.text = @"Err"; 
       } 
       */ 
      }]; 
[dataTask resume]; 

}

जब कार्यक्रम चलाया जाता है, nameLabel नहीं बदला गया है करने के लिए "Yay": यहाँ कोड है। हालांकि अगर मैं NSURLSessionDataTask लाइन से पहले नाम लेबल बदलने की कोशिश करता हूं, तो यह बदल जाता है।

+0

अगर यह आपकी मदद करता है तो कृपया नीचे दिए गए उत्तर का चयन करें। अगर आपके पास अभी भी उत्तर से संबंधित प्रश्न हैं तो टिप्पणी करने के लिए स्वतंत्र महसूस करें। – wigging

उत्तर

14

NSURLSessionDataTask पृष्ठभूमि धागे में चलता है। उपयोगकर्ता इंटरफ़ेस जैसे लेबल, बटन, टेबल व्यू इत्यादि में कुछ भी अपडेट करने के लिए, आपको मुख्य थ्रेड पर ऐसा करना होगा। आप completionHandler ब्लॉक से लेबल पाठ को अपडेट करना चाहते हैं तो आप तो जैसे मुख्य थ्रेड में लेबल अद्यतन करने की आवश्यकता:

static NSURLSession* sharedSessionMainQueue = nil; 
if(!sharedSessionMainQueue){ 
    sharedSessionMainQueue = [NSURLSession sessionWithConfiguration:nil delegate:nil delegateQueue:[NSOperationQueue mainQueue]]; 
} 

NSURLSessionDataTask *dataTask = 
[sharedSessionMainQueue dataTaskWithURL:url completionHandler:^(NSData *data, 
           NSURLResponse *response, 
           NSError *error){ 
    //now will be on main thread 
}]; 
[dataTask resume]; 

यह आपको मूल व्यवहार देता है:

dispatch_sync(dispatch_get_main_queue(), ^{ 
    nameLabel.text = @"yay!"; 
}); 
12

इस जादू की कोशिश मुख्य थ्रेड पर पूर्ण हैंडलर के साथ NSURLConnection की ताकि आप UI को अपडेट करने के लिए सुरक्षित हों। हालांकि, आप डाउनलोड को पार्स करना चाहते हैं या कुछ भारी प्रसंस्करण करना चाहते हैं, उस स्थिति में आप ऑपरेशन कतार के पृष्ठभूमि थ्रेड पर पूरा करने वाले हैंडलर से लाभ उठा सकते हैं और फिर अंतिम चरण के रूप में मुख्य थ्रेड पर dispatch_sync का उपयोग कर सकते हैं।

+2

+1 - यह एक बेहतर तरीका है, क्योंकि आप * वैकल्पिक रूप से * पृष्ठभूमि धागे पर अतिरिक्त कार्यों को चलाने का चयन कर सकते हैं, और मान लें कि सब कुछ मुख्य धागे पर चल रहा है। –

+0

हम्म, जोनाथन यदि आप इस विधि का उपयोग पूरा करने वाले ब्लॉक में सब कुछ करते हैं, तो मुख्य धागे पर (केवल हो सकता है) होगा। – Fattie

+0

जो वह आवश्यक है यदि आवश्यक हो तो मुख्य थ्रेड समापन ब्लॉक से पृष्ठभूमि धागे बनाएं। – malhal

संबंधित मुद्दे