2015-03-19 5 views
5

मैं काफी ऑब्जेक्टिव-सी & लिए नया हूँ गतिशील success ब्लॉक में अंदर की AFHTTPRequestOperationManager से

@property (strong, nonatomic) NSMutableArray *allCategories

का मूल्य बदलना होगा।
[self.allCategories addObject:tempObject];
लूप में पुनरावृत्ति करते समय allCategories के मान को परिवर्तित नहीं करता है।

वैरिएबल को
self.allCategories = [[NSMutableArray alloc]init];
में देखा गया है DidLoad में।ब्लॉक के अंदर से एक गैर-स्थानीय (वैश्विक) चर को कैसे संशोधित करें?

मैं भी __block NSMutableArray *tempCategories = [[NSMutableArray alloc]init]; के रूप में एक अस्थायी चर बनाने AFHTTPRequestOperationManager वस्तु शुरू करने से पहले की कोशिश की है। tempCategories अपने मूल्य को भी बरकरार नहीं रखता है।

क्या हो रहा है यह पता नहीं लगा सकता है।

संपादित
असुविधा
viewDidLoad के लिए खेद है निम्नलिखित कोड
self.allCategories = [[NSMutableArray alloc]init];
[self loadData];

है यहाँ कोड

-(NSMutableArray *)loadData 
{ 
    __block NSMutableArray *tempCategories = [[NSMutableArray alloc]init]; 

    manager = [AFHTTPRequestOperationManager manager]; 

    [manager GET:kAPICategoryList 
     parameters:nil 
     success:^(AFHTTPRequestOperation *operation, id responseObject) { 

      // downcast id to NSMutableDictionary 
      NSMutableDictionary *json = (NSMutableDictionary *)responseObject; 

      // check if dictionary is non nil has at least 1 element 
      if (json != nil && [json count] >= 1) { 

       // NSLog(@"json:\t%@", json); 

       // check json is non nil & has success message 
       if ([json objectForKey:kAPIKeyCategoryRoot] != nil) { 

        NSArray *arrCategoriesRoot = [json objectForKey:kAPIKeyCategoryRoot]; 

        // check categories has some data 
        if (arrCategoriesRoot.count >= 1) { 

         for (int i = 0; i < arrCategoriesRoot.count; i++) { 

          SomeModel *pCategory; 

          NSDictionary *dctCategorySingle = [arrCategoriesRoot objectAtIndex:i]; 

          // check category has sub category 
          if ([dctCategorySingle objectForKey:kAPIKeyCategorySubCategory] != nil) { 
           // create category with sub category 
           pCategory = [[SomeModel alloc]initWithSubCategorisedCategoryID:[dctCategorySingle objectForKey:kAPIKeyCategoryID] 
                           name:[dctCategorySingle objectForKey:kAPIKeyCategoryName] 
                          image:kIMGCategoryDefault 
                         subCategory:[dctCategorySingle objectForKey:kAPIKeyCategorySubCategory]]; 
          } else{ 
           // create just a category 
           pCategory = [[SomeModel alloc]initWithCategoryID:[dctCategorySingle objectForKey:kAPIKeyCategoryID] 
                       name:[dctCategorySingle objectForKey:kAPIKeyCategoryName] 
                       image:kIMGCategoryDefault]; 
          } // else just 
          [tempCategories addObject:pCategory]; 
          [_allCategories addObject:pCategory]; 
         } // for 
         NSLog(@"categories count %lu", [self.allCategories count]); 
        } // if count >= 1 
       } 
       else if ([json objectForKey:kAPIRespMsgCategoryFetchErrKey] != nil) { 
        [Utility showAlertWithTitle:kAPIRespMsgCategoryFetchErrKey 
             message:[json objectForKey:kAPIRespMsgCategoryFetchErrVal] 
              button:kMsgButtonOkayTtl]; 
       } 
      } else { 
       // error in login => enable login 
       NSLog(@"%@", kMsgNetworkEmptyJSON); 
      } 
     } 
    // network error 
     failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
      NSLog(@"error %@", [error localizedDescription]); 
     }]; 
    NSLog(@"tempCategories count %lu", [tempCategories count]); 
    return tempCategories; 
} 

है यहाँ उत्पादन प्रपत्र NSLog:

2015/03/19 18: 27: 17.845 MyProject [4011 : 121268] viewDidLoad
2015-03-19 18: 27: 18.133 मायप्रोजेक्ट [4011: 121268] temp श्रेणियां 0
2015-03-19 18: 27: 18.136 मायप्रोजेक्ट [4011: 121268] संख्याऑफ्रोइन्सइक्शन गणना 0
2015/03/19 18: 27: 18.137 MyProject [4011: 121,268] numberOfRowsInSection गिनती 0
2015/03/19 18: 27: 19.019 MyProject [4011: 121,268] श्रेणियों गिनती 20

जब loadData खत्म allCategories नहीं है इसमें डेटा (शून्य)।

+0

फोन आप कोड पोस्ट कृपया बना सकते हैं कि ऐसा करने के लिए? – jakedunc

+0

आपने पर्याप्त जानकारी प्रदान नहीं की है। आपको क्या लगता है कि यह मूल्यों को नहीं बदल रहा है? उस कोड को पोस्ट करें जो आपके AFHTTPRequestOperationManager को कॉल करता है, साथ ही वह कोड जहां आप निष्कर्ष निकालते हैं कि addObject को कॉल कुछ भी नहीं कर रहा है। मेरा अनुमान है कि आप समझ नहीं पाते कि एसिंक पूरा करने के तरीके कैसे काम करते हैं, और उम्मीद करते हैं कि जैसे ही आप कॉल करते हैं, वैल्यू को बदला जा सकता है। –

+0

सावधान रहें। आप यह सुनिश्चित नहीं कर सकते कि आपका पूरा करने वाला ब्लॉक किस धागे से वापस आ रहा है, जिसका अर्थ है कि आपको किसी भी तरह से अपनी सरणी थ्रेडसेफ तक पहुंचने की आवश्यकता हो सकती है। यह एक कारण है कि एसिंक एप्लिकेशन में वैश्विक चर क्यों आदर्श नहीं है। – damian

उत्तर

0

इस प्रयास करें:

dispatch_async(dispatch_get_main_queue(), ^{ 
[self.allCategories addObject:tempObject]; 
}); 
0

मैं एक ही समस्या थी कुछ दिन पहले। मेरी समस्या यह थी कि मेरी सरणी शून्य लगती है, viewdidload विधि में सरणी आवंटन आपके अनुरोध को viewDidLoad से पहले चलाया जा सकता है। यदि आप देखते हैं कि सरणी शून्य है तो एबोक अलग-अलग जगह को डिबग के साथ जांचें। पीएस: मैं विशेषज्ञ नहीं हूं लेकिन यह मेरे साथ एक ही समस्या हो सकती है।

0

निम्नलिखित पंक्ति के साथ NSMutableArray परिभाषित करें।

@property (nonatomic, strong) NSMutableArray * arrData; 

में viewDidLoad

- (void)viewDidLoad { 

    [super viewDidLoad]; 

    self.arrData = [NSMutableArray array]; 
} 

कॉल initialize किसी भी UIButton action साथ विधि output OR working behavior

- (void) TestMethod { 

    dispatch_queue_t queue = dispatch_queue_create("myQueue", 0); 

    dispatch_async(queue, ^{ 
     AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL urlWithEncoding:@"https://www.google.co.in/?gws_rd=ssl"]]; 
     [httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]]; 
     [httpClient setDefaultHeader:@"Accept" value:@"application/json"]; 
     [httpClient setParameterEncoding:AFJSONParameterEncoding]; 
     NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET" path:@"" parameters:nil]; 
     [request setTimeoutInterval:180]; 
     [AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"text/html"]]; 
     dispatch_semaphore_t sema = dispatch_semaphore_create(0); 

     AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) 
              { 
               [self.arrData addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"test",@"t3da",@"adsf",@"afds", nil]]; 
               dispatch_semaphore_signal(sema); 
              } failure:^ (NSURLRequest *request, NSURLResponse *response, NSError *error, id json){ 

               [self.arrData addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"test",@"t3da",@"adsf",@"afds", nil]]; 
               dispatch_semaphore_signal(sema); 
              }]; 

     [operation start]; 

     dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 
     DLog(@"arrData = %@",self.arrData); 
    }); 
} 
+0

असाइन नहीं किया गया है 'ग्लोबल मैनेजर' – Smarto

4

जहाँ तक देखने के लिए मुझे पता है के रूप में यह इस तरह से काम करना चाहिए निम्नलिखित .. क्या आप वाकई अपनी सफलता कर रहे हैं allCategories की सामग्री की जांच करने से पहले ब्लॉक को बुलाया जा रहा है?

एसिंक्रोनस रूप से एक सफलता ब्लॉक काम है, जो यह केवल निष्पादित किया जाएगा जब RequestOperation पूरा हो गया है इसका मतलब है (एक लंबा समय लग सकता है जो अगर आप कुछ बड़ा डाउनलोड कर रहे हैं)

आप का मान प्राप्त करने के लिए कोशिश कर रहे हैं allCategories से पहले सफलता ब्लॉक निष्पादित किया गया है, आपको वह उम्मीद नहीं मिलेगी जो आप उम्मीद कर रहे हैं। मैं आपकी सफलता ब्लॉक पर ब्रेकपॉइंट्स या NSLog का उपयोग करने की अनुशंसा करता हूं यह देखने के लिए कि यह निष्पादित किया गया है या नहीं, जब आपको लगता है कि यह ऐसा कर रहा है।

जैसे

... 
successBlock:^(AFHTTPRequestOperation *operation, id responseObject) 
{ 
    NSLog(@"Success"); 
    [self.allCategories addObject:tempObject] 
    }]; //End of request 

[operation start]; //Begin executing the AFHTTPOperation 

NSLog("%@",self.allCategories.description); //probably nil or empty 
//since the success block hasn't been called yet 

संपादित करें:

मैं हालांकि, इससे पहले कि आप async आपरेशन द्वारा निर्धारित किया गया है एक मूल्य के लिए लौट रहे हैं के रूप में, एक async आपरेशन से एक मूल्य के वापस जाने के लिए मैं एक बार देख ले सुझाव है इस answer और this एक के लिए। इसके अलावा आपको थोड़ा सा एसिंक कार्य कैसे काम करना चाहिए।

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

आप एक कस्टम पूरा होने के ब्लॉक

- (void)myCustomMethodWithCompletionBlock: (void (^)(NSArray *))completion { 
    //Do your request 
    //... 
    successBlock:^(AFHTTPRequestOperation *operation, id responseObject) 
    { 
     NSLog(@"Success"); 
     completionBlock(allCategories); 
    }]; //End of request 
} 
इस बीच अपने मुख्य विधि में

के साथ एक सरल विधि आप

[self myCustomMethodWithCompletionBlock:^(NSArray *allCategories) { 
    self.allCategories = allCategories; 
    //Do other stuff you need to with that variable since now you are 
    //sure the value will be set unless the operation failed 
    }]; 
संबंधित मुद्दे