2013-03-13 53 views
0

我試圖在tableview中放入正確返回的JSON的結果。 問題是我只能訪問返回信息的塊內的數據,甚至將結果分配給實例變量。 我的代碼如下:目標C - JSON數據在正確返回後不可用

NSURL *url = [NSURL URLWithString:@"http://www.my_url.com.br/app/?type=list&info=15,16&lat=some_data&long=some_data"]; 

ASIHTTPRequest *_request = [ASIHTTPRequest requestWithURL:url]; 
ASIHTTPRequest *request = _request; 

request.requestMethod = @"POST"; 
[request addRequestHeader:@"Content-Type" value:@"application/json"]; 

[request setDelegate:self]; 
[request setCompletionBlock:^{ 
    NSString *responseString = [request responseString]; 

    NSLog(@"Response: %@", responseString); 
    NSDictionary *root = [NSJSONSerialization JSONObjectWithData:request.responseData options:0 error:nil]; 
    self.data = [root objectForKey:@"listing"]; 

    NSLog(@"Data returned: %@", data); //Everything works well. The data returned is printed correctly 

}]; 
[request setFailedBlock:^{ 
    NSError *error = [request error]; 
    NSLog(@"Error: %@", error.localizedDescription); 
}]; 

[request startAsynchronous]; 

NSLog(@"Data only: %@", data); //At this point, the "data" content is nil 

這是我的 「ListDataController.h」 文件定義:

@interface ListDataController : UITableViewController{ 
ApplicationCell *tmpCell; 
    NSArray *data; 
    UILabel *status ;  
UINib *cellNib; 
} 

@property (nonatomic, retain) IBOutlet ApplicationCell *tmpCell; 
@property (nonatomic, retain) NSArray *data; 

的JSON返回: 數據自:( { 圖標=「Baseball.png 「; Name = Baseball; NumRatings = 106; Price =」$ 2.98「; Publisher =」Super Sportz,Inc.「; Rating =」3.5「; }, { Icon =「Checkers.png」; 名稱=跳棋; NumRatings = 87; 價格=免費; Publisher =「Gameitoids,Inc.」; 評分= 4; } )

問題是:爲什麼我不能訪問塊外的實例變量「data」,甚至將它分配給json的結果呢?

回答

1

完成響應可以在塊外部訪問data,但它被設置爲nil。您可能正確設置了data,只是不在您想的那一刻。

當你執行最後的日誌時,完成塊還沒有運行。請求是異步,這意味着完成塊將在未來的某個時間點執行。這是瞭解使用塊時的一個關鍵概念。

UPDATE

要procress數據一旦被retreived,你可以調用從完成塊的目標:

[request setCompletionBlock:^{ 
    NSString *responseString = [request responseString]; 

    NSLog(@"Response: %@", responseString); 
    NSDictionary *root = [NSJSONSerialization JSONObjectWithData:request.responseData options:0 error:nil]; 
    self.data = [root objectForKey:@"listing"]; 

NSLog(@"Data returned: %@", data); //Everything works well. The data returned is printed correctly 

    [self handleData:self.data]; // you would have to define this method your self 

}]; 

有一點要考慮,如果你正在更新UI基於self.data,你會想確保你在主線程上執行handleData

幾個環節:

0

這裏會發生什麼事是你的日誌

NSLog(@"Data only: %@", data); //At this point, the "data" content is nil 

將獲得data.You之前使用異步請求使用塊是執行將發生在一個單獨的線程不影響主線程執行

執行良好

,並在單獨的線程中完成竣工塊得到.Hence響應只加載執行到的數據在這一點上只有

爲了更好的理解性

0123在這兩個記錄和完成塊個
  • 認沽斷點

你可以看到在日誌中執行完畢塊之前發生

編輯: 可以響應後做的操作在完成塊分配給data

[request setCompletionBlock:^{ 
     NSString *responseString = [request responseString]; 

     NSLog(@"Response: %@", responseString); 
     NSDictionary *root = [NSJSONSerialization JSONObjectWithData:request.responseData options:0 error:nil]; 
     self.data = [root objectForKey:@"listing"]; 

     NSLog(@"Data returned: %@", data); //Everything works well. The data returned is printed correctly 


     //DO here WHATEVER you want to do after getting response 
    //eg: 
     [table reloadData] 


    }]; 

請求時獲取所有數據將執行完成bl ock.So任何你想要做的事情後,可以在完成塊

+0

我已經注意到了這一點,通過分析日誌和毫秒的操作,但不明白爲什麼發生。感謝澄清。 但我該如何解決這個問題?我需要應用程序等待JSON的返回,然後將其分配給將由tableview使用的變量。 – Lano 2013-03-13 15:05:12

+0

是的,你可以在完成塊中做到這一點 – 2013-03-13 15:09:10

+1

你可以通過同步請求數據來解決這個問題。你不希望這樣做,因爲那時你的應用程序將凍結在這一點上,直到最終收到數據。在某些情況下可能需要很長時間(直到ip超時)。 – 2013-03-13 15:10:26

0
  1. 時間(如上面的2個答案)
  2. 寫入到生活外塊的變量,你必須使用變量聲明前的__block指令。我不確定實例變量是否是特殊的,但是要確保你可以使用一些臨時變量來存儲結果,然後將其最終分配給伊娃。
0
NSLog(@"Data returned: %@", data); //Everything works well. The data returned is printed correctly 

好。你有什麼問題?這是完成塊。它在接收到所有數據時執行。在此時間點之前訪問數據的任何情況最終都將以零爲最終結果,或者在最差情況下以最長的數據結束/超時/不可預測的數據。