2016-01-11 33 views
0

我想解析一個使用AFNetworking和MJExtensions的JSON鏈接。 請參閱代碼中的評論。我如何將數據保存在塊代碼之外?

- (void)viewDidLoad { 
     [super viewDidLoad]; 

     NSString *apiURL = @"https://api.forecast.io/forecast/APIKEY/Lat,Long"; 

     NSURL *URL = [NSURL URLWithString:apiURL]; 

     AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
     [manager GET:URL.absoluteString parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) { 
      weatherDict = (NSDictionary *)responseObject; 
      weather = [WeatherClasses mj_objectWithKeyValues:weatherDict]; 


      //---------------------- 
      //when i set the label.text here, the label shows whatever the JSON value is 
      self.apparentTemperature.text = [NSString stringWithFormat:@"%f", weather.currently.apparentTemperature]; 
      NSLog(@"Temp: %f", weather.currently.apparentTemperature); 

     } failure:^(NSURLSessionTask *operation, NSError *error) { 
      NSLog(@"Error: %@", error); 
     }]; 
     //-------------------------- 
     //but if i set the label here, its always 0 (or nil for NSString) 
     self.apparentTemperature.text = [NSString stringWithFormat:@"%f", weather.currently.apparentTemperature]; 
    } 

而在成功的塊,我的字典裏有數據,但是當我走出成功的塊,字典是零。我怎樣才能讓字典不會在AFHTTPSessionManager中設置爲零?

使用__block不起作用。

回答

1

//but if i set the label here, its always 0 (or nil for NSString)

這是因爲該代碼運行網絡請求完成之前,因此數據不存在。當你將一個塊傳遞給異步方法(如網絡調用)時,該塊通常會在之後執行您調用的方法已退出。

使用__block不起作用。

毫不奇怪。 __block確保如此標記的變量本身在塊內使用,而不是在塊的上下文中重複使用,但不會使數據恢復得更快。

這裏的正確解決方案是在請求的完成塊中設置標籤 - 這就是的完成塊。

我該如何將數據保存在塊代碼之外?

不要嘗試 - 沒有理由不在塊內設置變量。

0

使用__block關鍵字時,您decalre weatherDict超出塊代碼。

+0

我用'@interface ViewController(){ __block WeatherClasses * weather; __block NSDictionary * weatherDict; } @end '它的標籤仍顯示0 – highboi

+0

這是在viewcontroller.m – highboi

1

塊是異步的,這意味着self.apparentTemperature.text = [NSString stringWithFormat:@"%f", weather.currently.apparentTemperature];可能會在設置了weather的塊之前執行。

這就是爲什麼self.apparentTemperature.text始終是nil以外的塊。

爲了解決這個問題,只需調用一個函數,您可以在塊的末尾(但在塊內)設置UI元素,這樣它將在塊執行後調用。

0

你可以只使用一個信號:

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
[manager GET:URL.absoluteString parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) { 
    ... 

    dispatch_semaphore_signal(semaphore); 
}]; 

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 
self.apparentTemperature.text = [NSString stringWithFormat:@"%f", weather.currently.apparentTemperature]; 

但我不認爲是這樣。正如人們所說的那樣,正確的做法是異步的。

簡單地把你的代碼設置在塊後面的標籤或根本不包含它。此代碼的唯一目的是在未調用塊的情況下設置默認值。

只要你有來自服務器的響應,你的塊將被調用,你應該把你的邏輯放在裏面,就像現在一樣。

相關問題