5

मैं प्रोग्रामेटिक रूप से एक एक्सएलएस शीट बनाने की कोशिश कर रहा हूं। शीट भरने के लिए, मैं कई NSURLConnection लगभग 100 बना रहा हूं। अभी मेरा दृष्टिकोण है:एकाधिक NSURL कनेक्शन को संभालने का सबसे अच्छा तरीका

  1. कनेक्शन बनाएं और डेटा को सरणी में संग्रहीत करें। इस सरणी में 100 वस्तुएं हैं।
  2. अब पहली वस्तु लें और कनेक्शन को कॉल करें। डेटा स्टोर करें। और सरणी में दूसरी वस्तु के साथ दूसरा कनेक्शन बनाओ। यह सरणी में अंतिम वस्तु तक जारी है।

100 कनेक्शन समाप्त करने में औसत 14 सेकंड लगते हैं। प्रतिक्रिया को तेजी से प्राप्त करने के लिए NSURLConnection को लागू करने का कोई तरीका है?

गुण की घोषणा:

@property (nonatomic,strong) NSURLConnection *getReportConnection; 
@property (retain, nonatomic) NSMutableData *receivedData; 
@property (nonatomic,strong) NSMutableArray *reportArray; 

सरणी आरंभ किया जा रहा viewDidLoad में:

reportArray=[[NSMutableArray alloc]init]; 

एक बटन कार्रवाई में NSURLConnection शुरु कर रहा है:

कल तक

मैं जैसे बुनियादी दृष्टिकोण का पालन किया

/initialize url that is going to be fetched. 
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"****/%@/crash_reasons",ID]]; 

//initialize a request from url 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 
[request addValue:tokenReceived forHTTPHeaderField:@"**Token"]; 

[request setHTTPMethod:@"GET"]; 
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 

//initialize a connection from request 
self.getReportConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

प्राप्त डेटा का संसाधन: एक पूर्ण होने के बाद किसी अन्य कनेक्शन कॉलिंग

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data{ 
if (connection==_getVersionConnection) { 

    [self.receivedData_ver appendData:data]; 

    NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

    NSError *e = nil; 
    NSData *jsonData = [responseString dataUsingEncoding:NSUTF8StringEncoding]; 

    NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:jsonData options: NSJSONReadingMutableContainers error: &e]; 
    [JSON[@"app_versions"] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
     if (![obj[@"id"] isEqual:[NSNull null]] && ![reportArray_ver containsObject:obj[@"id"]]) { 

      [reportArray_ver addObject:obj[@"id"]]; 

     } 
     NSLog(@"index = %lu, Object For title Key = %@", (unsigned long)idx, obj[@"id"]); 
    }]; 

    if (JSON!=nil) { 
     UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"Version Reports succesfully retrieved" message:@"" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil]; 
     [alert show]; 
    } 
} 

} 

:

// This method is used to process the data after connection has made successfully. 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ 
    if (connection==getReportConnection) { 

      //check and call the connection again 
    } 
} 

और आज, मैं अन्य पाश उपयोग करने के बाद सभी कनेक्शनों एक आग sendAsync साथ NSURLConnection की कोशिश की , और यह बहुत अच्छी तरह से काम किया।

self.receivedData_ver=[[NSMutableData alloc]init]; 
__block NSInteger outstandingRequests = [reqArray count]; 
for (NSString *URL in reqArray) { 

    NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:URL] 
                 cachePolicy:NSURLRequestUseProtocolCachePolicy 
                timeoutInterval:10.0]; 

    [request setHTTPMethod:@"GET"]; 
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 


[NSURLConnection sendAsynchronousRequest:request 
            queue:[NSOperationQueue mainQueue] 
         completionHandler:^(NSURLResponse *response, 
              NSData *data, 
              NSError *connectionError) { 

          [self.receivedData appendData:data]; //What is the use of appending NSdata into Nsmutable data? 

          NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

          NSError *e = nil; 
          NSData *jsonData = [responseString dataUsingEncoding:NSUTF8StringEncoding]; 

          NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:jsonData options: NSJSONReadingMutableContainers error: &e]; 
          NSLog(@"login json is %@",JSON); 

          [JSON[@"app_versions"] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 


           if (![obj[@"id"] isEqual:[NSNull null]] && ![reportArray_ver containsObject:obj[@"id"]]) { 

            [reportArray_ver addObject:obj[@"id"]]; 

           } 

           NSLog(@"index = %lu, Object For title Key = %@", (unsigned long)idx, obj[@"id"]); 
          }]; 


          outstandingRequests--; 

          if (outstandingRequests == 0) { 
           //all req are finished 
           UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"Version Reports succesfully retrieved" message:@"" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil]; 
           [alert show]; 
          } 

         }]; 
} 

इस समय यह पुरानी प्रक्रिया की तुलना में 100 अनुरोध को पूरा करने के आधे समय ले लिया है, वहाँ किसी भी तेज़ तरीका मौजूद है asynReq के अलावा अन्य है? .क्या सबसे अच्छा परिदृश्य NSURLconnection और NSURLConnection with asyncReq उपयोग करने के लिए है?

+0

NSURL सत्र का उपयोग क्यों नहीं करते? NSURLConnection अब –

उत्तर

6

टिप्पणियों के एक जोड़े:

  1. उपयोग NSURLSession बजाय NSURLConnection (यदि आप आईओएस 7.0 के संस्करणों और अधिक से अधिक समर्थन कर रहे हैं):

    for (NSString *URL in URLArray) { 
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; 
    
        // configure the request here 
    
        // now issue the request 
    
        NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
         // check error and/or handle response here 
        }]; 
        [task resume]; 
    } 
    
  2. आप पूरी तरह 100 अनुरोध जारी करने के है, तो , फिर उन्हें अपने sendAsynchronousRequest कार्यान्वयन (या मेरे dataTaskWithRequest) की तरह समवर्ती रूप से जारी करें, अनुक्रमिक रूप से नहीं। यही वह है जो बड़े प्रदर्शन लाभ को प्राप्त करता है।

    नोट, हालांकि, आप कोई आश्वासन है कि वे पूरी तरह से क्रम में है कि आप उन्हें जारी करेंगे, ताकि आप कुछ संरचना का समर्थन करता है कि कि (जैसे NSMutableDictionary का उपयोग या तो प्लेसहोल्डर के साथ NSMutableArray पहले से भर उपयोग करना चाहते हैं जाएगा है आप सरणी में कोई आइटम जोड़ने के बजाय बस किसी विशेष अनुक्रमणिका पर प्रविष्टि को अपडेट कर सकते हैं)।

    नीचे की रेखा, जागरूक रहें कि वे अनुरोध के अनुसार उसी क्रम में समाप्त नहीं हो सकते हैं, इसलिए सुनिश्चित करें कि आप इसे उचित तरीके से संभाल लें।

  3. यदि आप 100 अलग-अलग अनुरोध रखते हैं, तो मैं सुझाव दूंगा कि आप इसे वास्तव में धीमी नेटवर्क कनेक्शन पर जांचें (उदाहरण के लिए नेटवर्क लिंक कंडीशनर का उपयोग वास्तव में खराब नेटवर्क कनेक्शन को अनुकरण करने के लिए करें; NSHipster discussion देखें)। समस्याएं हैं (टाइमआउट, यूआई हिचकी, इत्यादि) जो धीमे कनेक्शन पर ऐसा करते समय केवल दिखाई देते हैं।

  4. लंबित अनुरोधों की संख्या के काउंटर को कम करने के बजाय, मैं प्रेषण समूहों या ऑपरेशन कतार निर्भरताओं का उपयोग करने का सुझाव दूंगा।

    dispatch_group_t group = dispatch_group_create(); 
    
    for (NSString *URL in URLArray) { 
        dispatch_group_enter(group); 
    
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; 
    
        // configure the request here 
    
        // now issue the request 
    
        NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
         // check error and/or handle response here 
    
         // when all done, leave group 
    
         dispatch_group_leave(group); 
        }]; 
        [task resume]; 
    } 
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{ 
        // do whatever you want when all of the requests are done 
    }); 
    
  5. संभव हो तो, आप वेब सेवा refactor ताकि आप एक अनुरोध है कि डेटा के सभी रिटर्न जारी कर रहे हैं हैं या नहीं। यदि आप आगे प्रदर्शन सुधार की तलाश में हैं, तो शायद यह करने का तरीका है (और यह 100 अलग-अलग अनुरोध जारी करते समय शामिल कई जटिलताओं से बचाता है)।

  6. Btw, यदि आप प्रतिनिधि आधारित कनेक्शन का उपयोग, जैसे आप अपने मूल प्रश्न में किया था, तो आप नहींdidReceiveData में डेटा को पार्स किया जाना चाहिए। यह केवल NSMutableData पर डेटा जोड़ना चाहिए। connectionDidFinishLoading प्रतिनिधि विधि में सभी पार्सिंग करें।

    यदि आप ब्लॉक-आधारित कार्यान्वयन पर जाते हैं, तो यह समस्या दूर हो जाती है, लेकिन आपके कोड स्निपेट पर केवल एक अवलोकन।

+0

@ रोब- मैंने लूप में यूआरएल सत्र रखने की कोशिश की लेकिन, इसे निष्पादित नहीं किया गया है। किसी भी तरह, यूआरएल सत्र के अंदर कोड ब्लॉक छोड़ दिया जा रहा है। – ZeeroCool77

+0

@ T_77 - ठीक है, फिर लॉग स्टेटमेंट्स या ब्रेकपॉइंट्स के साथ कुछ बुनियादी निदान करें, यह सुनिश्चित कर लें कि आप अपनी 'रेज़्यूमे' लाइन को मारना चाहते हैं। लेकिन 'NSURLSession' का उपयोग करने के लिए यह पैटर्न बहुत मानक है, इसलिए मुझे संदेह है कि समस्या असंबंधित है। क्या अनुरोध सही तरीके से शुरू हो रहे हैं? [चार्ल्स] (http://charlesproxy.com) का उपयोग कर अनुरोध देखने का प्रयास करें। – Rob

+0

@ रोब-यह काम किया। मैं भी आपका जवाब उखाड़ फेंक सकता हूं, लेकिन खेद है कि मेरे पास पर्याप्त प्रतिनिधि नहीं है !!! Gr8 उत्तर के लिए धन्यवाद। – ZeeroCool77

1

sendAsynchronous का उपयोग कोड संगठन को बेहतर बनाने का एक शानदार तरीका है। मुझे यकीन है कि कुछ सावधानीपूर्वक जांच के साथ, हम मार्जिन पर गति को बेहतर बना सकते हैं, लेकिन गति में उल्लेखनीय रूप से सुधार करने का तरीका 100 अनुरोध नहीं करना है।

यदि प्रतिक्रिया निकाय छोटे हैं, तो एक अंतराल बनाएं जो परिणामों के संयोजन का उत्तर देता है।

यदि प्रतिक्रिया निकाय बड़े हैं, तो आप इस समय उपयोगकर्ता की जरूरतों के मुकाबले अधिक डेटा का अनुरोध कर रहे हैं। यूआई को केवल उस यूजर को पकड़ें जिसे उपयोगकर्ता को देखना है, और बाकी को चुपचाप प्राप्त करें (... या शायद चुपचाप, आलसी से बेहतर हो)।

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

+0

कनेक्शन को बनाते समय हटा दिया गया है, मैं केवल प्रगति पट्टी प्रदर्शित कर रहा हूं और कनेक्शन पूरा होने के बाद इसे हटा रहा हूं। – ZeeroCool77

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

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