0

我正在開發應用程序,它使用NSURLConnection發送和接收JSON數據,但我在viewcontroller中有這個連接和它的delagate方法,這對於我猜測的MVC是不正確的。我想要整個連接的分離類,但有問題,我無法檢測然後在viewcontroller,當連接完成加載,所以我無法得到接收的數據。什麼是正確的方法來做到這一點?正確使用NSURLConnection

但是,viewcontrollers裏面的這個洞(非MVC)NSURLConnection對我的應用程序來說工作正常,除了一種情況 - 當我需要使用tableview時,它是viewcontroller的一部分 - 也是此tableview的數據源和委託。看起來好像tableview試圖創建單元格,在連接完成加載之前,我覺得有點奇怪,因爲在tableView方法中:numberOfRowsInSection:我已經有了我需要的數據,並且我認爲在我配置之前調用了這個方法在tableView:CellForRowAtIndexPath中的單元格:...但我錯了。有人可以解釋我在這裏發生了什麼,以及如何解決這個問題? (也使用MVC的正確與NSURLConnection的第一部分)

回答

1

實現你的JSON的客戶端類的委託協議,如:

@protocol JSONClientDelegate <NSObject> 
... 
- (void) connectionFinishedLoading; 
... 
@end 

@interface JSONClient 
{ 
    id<JSONCLientDelegate> delegate; 
} 
@property (nonatomic, assign) id<JSONClientDelegate> delegate; 
-(void) getJSON; 
@end 

@implementation JSONClient 

- (void) getJSON 
{ 
    ... 
    [NSURLConenction connectonWithRequest:request delegate:self]; 
    ... 
} 

- connectionDidFinishLoading:(NSURLConnection*) connection 
{ 
    [delegate connectionFinishedLoading]; 
} 

@end 

然後,讓你的ViewController實現委託協議:

@interface MyViewController : UIViewController <JSONClientDelegate> 
... 
- (void) doFoo; 
... 
@end 

@implementation MyViewController 

- (void) doFoo 
{ 
    ... 
    JSONClient* client = [JSONClient new]; 
    client.delegate = self; 

    [client getJSON]; 
    ... 
} 

- (void) connectionFinishedLoading 
{ 
    // Connection finished - do things here. 
} 

@end 

請注意,這是一個非常簡短的例子 - 我已經削減了幾個角以節省一些空間。我相信你可以在兩條線之間閱讀並填補空白 - 如果沒有(即我的例子不清楚),請告訴我,我會進一步闡述。

0

至於問題的第一部分,你可以得到更多的MVC設計,如果你:

  1. 實現你的JSON/NSURLConnection的東西,在模型類,這也實現了委託協議,並盡一切必要的處理響應;

  2. 當處理響應時,視圖控制器發送消息;您可以爲此定義一個自定義委託(即,發送給在ad-hoc協議中定義的控制器的特定消息),或者簡單地使用通知,該通知允許更多的解耦,並且可能更易於實現(但更多在運行時很昂貴);

  3. 視圖控制器責任在接收到該消息時正在進行更新以反映新數據。

作爲你的問題的第二部分,這是正常的表視圖只要它具有重繪自身,即創建細胞,之前的數據是存在的(因爲這需要時間)。

你需要做的是讓表格繪製自己爲空(可能顯示一個UI的「加載」位),並在視圖控制器被通知數據已被接收和處理時在表上調用reloadData

如果遵循上面的指導原則,使您的設計根據MVC更加分離,這將是非常自然的。

編輯:關於你的最後一個問題:

我不知道在哪裏如何創建myArray對象,但是,作爲一般規則,我希望它是你的數據源對象的伊娃(如果我不正確地理解事情);所以,當你第一次創建它時,你應該確保它被保留;稍後,當您完成數據源時,您可以在dealloc中發佈它。您可以在幾種可能的方式之一保留myArray,如:

myArray = [[NSArray alloc] init...]; 
在這種情況下

alloc已經爲您提供了一個保留的對象;或:

myArray = [[NSArray arrayWith...] retain]; 
在這種情況下

,你需要保留通過便捷構造對象返回(返回一個自動釋放的對象);

self.myArray = [NSArray arrayWith...]; 
在這種情況下

,你並不需要,如果myArray屬性被聲明爲retain的保留。

在所有以前的情況下,你做的是確保對象的保留數至少爲1,所以它不是由在某一時刻的框架釋放。如果不這樣做意味着,在某個時間點你的對象將取消自動釋放,這是很可能發生之前你的數據在那裏,即執行tableView:cellForRowAtIndexPath之前。

希望這有助於...

+0

我發現返回的行和段數的數量的tableView之前調用方法:的cellForRowAtIndexPath - 就像我在我的問題寫...和,而我的陣列是不是填充有一些對象,的tableView:NumberOfRowsInSection返回0([myArray的計數]),所以該方法的tableView:的cellForRowAtIndexPath甚至沒有調用...這個方法被稱爲第一次陣列中填充對象...... – Michael

+0

之後。 .......奇怪的是,當我使用[[myArray的objectAtIndex:0] objectForKey:@「的myKey」]中的ViewController類的任何地方,一切都很好,但是當我用它在的tableView:的cellForRowAtIndexPath方法,與EXC_BAD_ACCESS – Michael

+0

應用chrashes我保留了陣列,現在它的作品...但我不明白爲什麼它沒有這個工作,可以請你解釋一下嗎?謝謝 – Michael