2013-04-23 35 views
0

我對iOS中的Web服務調用和線程是一種新手。我的應用程序中包含一個ViewController,其中包含一個tableview控件。我使用通過JSON Web服務獲取的數據填充表格。 JSON Web服務在其自己的線程中調用,在此期間我填充NSArrayNSDictionary範圍和線程在iOS中

我的數組和字典好像超出了範圍,因爲我的NSLog語句對於數組計數返回零,即使在fetchedData中數組已完全填充。

有人可以解釋爲什麼我的數組和字典對象在線程之外是空的嗎?


- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    NSString *serviceEndpoint = [NSString stringWithFormat: 
           @"http://10.0.1.12:8888/platform/services/_login.php?un=%@&pw=%@&ref=%@", 
           [self incomingUsername], [self incomingPassword], @"cons"]; 
    NSURL *url = [NSURL URLWithString:serviceEndpoint]; 
    dispatch_async(kBgAdsQueue, ^{ 
     NSData *data = [NSData dataWithContentsOfURL:url]; 
     [self performSelectorOnMainThread:@selector(fetchedData:) withObject:data waitUntilDone:YES]; 
    }); 

    NSLog(@"ARRAY COUNT: %d\n", [jsonArray count]); 
} 

-(void)fetchedData:(NSData*)responseData{ 
    NSError *error; 
    jsonDict = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error]; 
    jsonArray = [[jsonDict allKeys]sortedArrayUsingSelector:@selector(compare:)]; 
    for(NSString *s in jsonArray){ 
     NSLog(@"%@ = %@\n", s, [jsonDict objectForKey:s]); 
    } 
} 
+0

'ViewDidLoad'只在屏幕第一次加載時被調用。你確定'fetchedData'在此之前被調用嗎? – thegrinner 2013-04-23 13:43:44

回答

0

當您使用dispatch_async時,該位代碼不會阻止。這意味着在調用fetchedData之前觸發了您的數組計數日誌語句,因此您的字典和數組仍然是空的。查看日誌語句的順序 - 在記錄字典之前,您應該看到數組數。

// Executes on another thread. ViewDidLoad will continue to run. 
dispatch_async(kBgAdsQueue, ^{ 
    NSData *data = [NSData dataWithContentsOfURL:url]; 
    [self performSelectorOnMainThread:@selector(fetchedData:) withObject:data waitUntilDone:YES]; 
}); 

// Executes before the other thread has finished fetching the data. Objects are empty. 
NSLog(@"ARRAY COUNT: %d\n", [jsonArray count]); 

你需要完成填充您的TableView數據返回後(即FetchData:)。

+0

是的,這是非常有意義的,但現在我不知道如何糾正這個問題。我需要在線程上執行此操作,因爲它可能需要一些時間... – Pheepster 2013-04-23 13:51:00

+1

只需從fetchedData函數調用TableView的reloadData即可。 – Fostah 2013-04-23 13:52:38

+0

你應該在你的用戶界面上顯示它正在下載的一些信息 - 也許是一個微調器或者一個單元格,讀取類似於「獲取數據,這可能需要一分鐘」。這樣用戶就知道發生了一些事情。當'fetchData:'觸發你可以調用'reloadData'。或者,如果請求失敗,則可以觸發新的顯示消息。 – thegrinner 2013-04-23 13:53:18

0

viewDidLoad中的log語句應該報告數組是空的,因爲它在那時還沒有被填充。調用dispatch_async會導致代碼塊異步運行,並允許viewDidLoad函數在塊執行之前完成。這就是爲什麼你在viewDidLoad的結尾沒有任何數組。

0

您正試圖在填充jsonArray元素之前打印其數量。這是發生了什麼:

  1. 您準備URL
  2. 創建新的線程來獲取一些最新的。執行此線程可能需要一些時間(取決於連接速度和數據量)。
  3. 你而線程執行和fetchedData訪問jsonArray:當時還不叫

此外,建議: 不要使用dataWithContentsOfURL:方法。最好看看AFNetworking等網絡框架。