2014-09-19 27 views
2

我從零開始學習iOS編程。模型,塊和完成處理程序哦我的

我希望我的應用能夠從網站中提取XML。我在想,爲了符合MVC模式,我應該有一個模型類,它只是提供了一種方法來實現這一點(也許它也解析了XML並返回一個數組)。

麻煩的是,所有我發現教程教NSURLSession在視圖和控制器的情況下 - 所以編輯的appdelegate,或創建一個視圖控制器等

我從蘋果文檔下面的方法而且我現在有一個按鈕被按下時可以作爲IBAction運行(所以我可以運行它並輕鬆測試)。我想獲得它的工作,然後把它放在它自己的等級:

__block NSMutableData *webData; 

NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration]; 

NSURLSession *delegateFreeSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]]; 
[[delegateFreeSession dataTaskWithURL: [NSURL URLWithString:url] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) 
{ 
    NSLog(@"Got response %@ with error %@.\n", response, error); 
    NSLog(@"DATA:\n%@\nEND DATA\n", [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]); 
     webData = [[NSMutableData alloc] initWithData:data]; 
} 
]resume]; 

我眼前的問題是:

有人可以解釋這個處理程序是如何工作的,以及如何獲得data出來的呢?它正在工作,數據從網站獲取xml並將其記錄在控制檯上,但將其複製到webData不起作用,它編譯但不復制。 (我還在搞清楚爲什麼__block聲明允許webData潛入那裏首先!)

我更大的問題是,如果每個人都認爲這個過程的單獨模型類的想法是一個好主意。有沒有更好的設計方法?

謝謝!

+0

也許你查找。那裏的答案可能會給你提示什麼是錯的。 – 2014-09-19 15:55:56

+0

我已經看過那個頁面。我已經在使用委託自由會話,所以我不知道它是如何適用的......另外,我的完成處理程序正在執行,我根本不知道如何從中取出數據。 – MayNotBe 2014-09-19 16:33:59

+0

「複製」是什麼意思? – Unheilig 2014-09-19 17:00:24

回答

2

這可能只是一些關於異步塊如何工作的混淆。如果你這樣做:

__block NSMutableData *webData; 
// ... 

[[delegateFreeSession dataTaskWithURL: [NSURL URLWithString:url] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) 
{ 
    NSLog(@"within the block, did I get data: %@", data); 
    webData = [[NSMutableData alloc] initWithData:data]; 
}]resume]; 

NSLog(@"after the block, did I get data: %@", webData); 

您可能會看到的輸出,看起來像這樣:

after the block, did I get data: (null) 
within the block, did I get data: <NSData ... 

是怎麼回事?爲什麼塊之後的代碼先運行?數據在哪裏?問題在於我們對「之後」的定義。在塊運行之前,出現在塊之後的NSLog實際運行。只要dataRequest是開始就會運行。在請求有完成後,塊內部的代碼會運行。

將數據結果保存在該方法的本地塊變量中,這樣做不行。當您點擊該方法的結尾時,該值未初始化。塊在程序塊運行時對其進行初始化,但只要程序塊完成,該值就會被丟棄。

修復:處理塊內的數據。不要期望它在塊運行之後纔有效(這是在方法運行之後):

EDIT - 在塊中使用自我來調用方法,設置屬性等是100%的好方法。你需要注意保留週期只有當塊本身是自我的一個屬性(或保留一些自我的一個屬性),它是不是...

// don't do this 
//__block NSMutableData *webData; 
// ... 

[[delegateFreeSession dataTaskWithURL: [NSURL URLWithString:url] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) 
{ 
    NSLog(@"within the block, did I get data: %@", data); 
    NSMutableData *webData = [[NSMutableData alloc] initWithData:data]; 
    // do whatever you plan to do with web data 
    // write it to disk, or save it in a property of this class 
    // update the UI to say the request is done 

    [self callAMethod:data];  // fine 
    [self callAnotherMethod]; // fine 
    self.property = data;  // fine 
}]resume]; 

// don't do this, there's no data yet 
//NSLog(@"after the block, did I get data: %@", webData); 
+0

我試圖在塊之前(之前)NSLog。我不明白的是,如果我不能在塊中使用類屬性,我可以如何將它保存在類的屬性中?那有意義嗎?對不起,如果這應該是顯而易見的,但我真的是新來這 – MayNotBe 2014-09-19 21:53:40

+0

所以,我已經設法解析'data'到一個對象數組中,而在塊(甚至不需要'webData'。現在我怎麼得到這個數組離開塊並返回給調用者? – MayNotBe 2014-09-19 21:56:03

+0

@MayNotBe - 你可以在該塊中放置你希望的任何代碼,通常放在方法中的任何東西都可以,請參閱編輯 – danh 2014-09-19 22:12:54

相關問題