2013-12-22 34 views
0

我對iOS編程還比較陌生。這是一個讓我困惑很久的問題。我應該在哪裏準備我的數據?在awakeFromNib,viewDidLoad或其他東西

因此,在其中一個視圖控制器中,在將此視圖控制器壓入導航項之前,我將一個參數(如userId)傳遞給前一個視圖控制器的prepareForSegue中的參數。當這個視圖控制器正在根據前一個視圖控制器的userId加載(初始化)時,我正在進行網絡調用以獲取與此用戶相關的信息列表,然後將此信息填充到當前視圖控制器的模型中。

我應該把這個數據準備的邏輯放在哪裏?

+0

我的意思是你們所有的人都給了我一個很好的解決方案。 非常感謝大家。 – TypingPanda

回答

1

使用viewDidLoad:應該罰款共同故事板使用,因爲故事板不會重用視圖控制器。不管怎樣,對於我的視圖控制器使用方案的完整性,我傾向於使用這種模式:

  • 開始在viewWillAppear:
  • 停止異步加載遠程數據viewWillDisappear:

加載遠程數據這確保您的數據將始終更新爲當前的userId,因爲ID可能會在viewDidLoad後更改,例如在視圖控制器重用或在設置userId之前訪問.view屬性。

您還應該跟蹤您的數據是否已加載。例如,您可以創建一個名爲_isDataLoaded的私有布爾字段,在完成加載數據時將其設置爲true,並在取消加載數據或設置新的userId時將其設置爲false

概括起來,在我的想法的模式應該是這樣的:

@interface UserViewControler : UIViewController { 
    bool _isDataLoaded; 
    NSURLConnection _dataConnection; 
} 

@implementation UserViewController 

-(void) setUserId:(int)userId { 
    if (_userId != userId) { 
     _userId = userId; 
     _isDataLoaded = false; 
    } 
} 

-(void) viewWillAppear:(BOOL)animated { 
    if (!_isDataLoaded) { 
     _dataConnection = // init data connection here 
     _dataConnection.delegate = self; 
     [_dataConnection start]; 
    } 
} 

-(void) viewWillDisappear:(BOOL)animated { 
    if (_dataConnection) { 
     [_dataConnection cancel]; 
     _dataConnection = nil; 
     _isDataLoaded = false; 
    } 
} 

// NSURLConnection call this when finish 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    _isDataLoaded = true; 
    _dataConnection = nil; 
} 

// NSURLConnection call this when fail to load data 
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    _isDataLoaded = false; 
    _dataConnection = nil; 
} 

這取決於你用什麼框架來從遠程服務器上的數據,但該模式應該是這樣的。這將確保:

  • 只有當視圖出現時纔會加載數據。
  • 視圖控制器在消失後不會載入更多數據。
  • 如果是相同的userId,則不會再次下載數據。
  • 支持視圖控制器重用。
1
- (void) viewDidLoad { 
    [super viewDidLoad]; 
    // initialize stuff 
} 

雖然,它可能是更好的做網絡電話,並收集所有這些信息將包含所有信息的自定義類,然後執行SEGUE。然後,您在新視圖控制器中所做的所有操作都將從對象中拉出數據(這仍將在viewDidLoad中完成)。

可以說,這種方法可能會更好,因爲如果網絡出現問題,您可以顯示錯誤消息,然後不執行segue,爲用戶提供更簡單的方法來重新嘗試相同的操作,或者至少他們'在離開應用程序以檢查網絡設置並返回之後,將在頁面上重新嘗試相同的操作。

當然,你可以隨時繼續前進,如果出現網絡錯誤,可以繼續向後延伸,但我認爲這看起來不穩定。

此外,值得注意的是,如果你正在呈現與UICollectionViewUITableView的信息時,呈現邏輯可以(應該)被移出viewDidLoad進入收集/表數據源的方法。

0

我過去所做的是製作自定義初始化程序。

+(instancetype)initWithUserID:(NSString)userID; 

這裏是一個實現的例子。

+(instancetype)initWithUserID:(NSString *)userID { 
    return [[self alloc] initWithUserID:userID]; 
} 

-(id)initWithUserID:(NSString *)userID { 
    self = [self initWithNibName:@"TheNameOfTheNib" bundle:nil]; 
    if(self) { 
     _userID = userID; 
    } 
    //do something with _userID here. 
    //example: start loading content from API 
    return self; 
} 

-(void)viewDidLoad { 
//or do something with userID here instead. 
} 

我建議的另一件事是做一個加載數據和使用塊的自定義類。

然後,你可以做這樣的事情

[API loadDataForUserID:userID withCompletionBlock^(NSArray *blockArray) { 
    //in this case I changed initWithUserID to initWithUsers 
    [self.navigationController pushViewController:[NextController initWithUsers:blockArray] animated:YES]; 
} 
相關問題