[英]iOS 7 - Difference between viewDidLoad and viewDidAppear
對不起,這可能不是一個編程問題本身,而是更多關於iOS生命周期功能的性質的詢問。
我有一個應用程序,我有一個函數創建四個數組並通過數據庫查詢填充它們。 首先,我從viewDidLoad
函數調用該函數,但是,每當加載View時,在視圖實際出現之前需要花費時間(大約3-4秒)。 所以我做的是創建了一個activityViewIndicator
,我的viewDidLoad
函數看起來像:
- (void)viewDidLoad:(BOOL)animated{
[super viewDidLoad];
NSLog(@"viewDidLoad Entered");
[self.activityIndicatorView startAnimating];
partInput.delegate = self;
brandInput.delegate = self;
barcodeInput.delegate = self;
itemNameInput.delegate = self;
//initializeArrays is the function that initializes the arrays
[self initializeArrays];
[self.activityIndicatorView stopAnimating];
}
但是,這不起作用,因為當應用程序仍在上一個視圖中時會觸發viewDidLoad
函數。 視圖僅在viewDidLoad
完成后才會顯示。 所以我做的是將數組初始化移動到我的viewDidAppear
函數,它看起來像:
- (void)viewDidAppear:(BOOL)animated{
NSLog(@"viewDidAppear loaded successfully");
[self.activityIndicatorView startAnimating];
partInput.delegate = self;
brandInput.delegate = self;
barcodeInput.delegate = self;
itemNameInput.delegate = self;
[self initializeArrays];
[self.activityIndicatorView stopAnimating];
}
但是,當我部署它時,沒有任何延遲,使activityIndicatorView無用。
我的問題是,為什么我認為viewDidLoad
和viewDidAppear
之間存在“性能差異”?
請每次按照以下查看控制器生命周期。 您將以這種方式對應用程序的編碼和性能感到驚訝。
我將指向Apple的文檔,因為我認為需要對View Controller生命周期進行更多解釋,而不僅僅是回答你的問題。
最終,您的視圖控制器具有生命周期:
init - 但是您初始化視圖控制器
viewWillLoad / viewDidLoad - 在構造視圖時調用(通過第一次調用通過它的視圖屬性檢索視圖控制器的UIView - 也稱為延遲加載)
viewWillAppear: - 當視圖准備立即出現(動畫==否)或查看轉換(動畫==是)時
viewDidAppear: - 如果未取消視圖外觀並且視圖控制器的視圖完全顯示
viewWillDisappear: - 補充viewWillAppear:
viewDidDisappear: - 補充viewDidAppear:
viewWillUnload / viewDidUnload - 由於內存限制而卸載視圖時不推薦使用的API(不再擔心這些)
dealloc - 視圖控制器本身正在被釋放
最后,我相信您的問題可能是您使用數組初始化阻止主線程。 您應該閱讀異步編程,但在此期間您可以執行以下操作:
- (void)viewDidLoad
{
[super viewDidLoad];
// other stuff
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf initializeArraysSynchronously];
dispatch_async(dispatch_get_main_queue(), ^{
strongSelf.doneIntializingArrays = YES;
[strongSelf.activityIndicatorView stopAnimating];
});
}
});
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (!self.doneInitializingArrays) {
[self.activityIndicatorView startAnimating];
}
}
viewDidLoad:和viewDidAppear:之間絕對沒有性能差異。 兩者都是在主線程上運行的普通函數。 如果你的initializeArrays方法加載需要3秒鍾,那么無論你調用哪種方法都需要3秒。 由於您沒有顯式更改線程,因此調用initializeArrays的任何函數在完成之前都不會退出。
對[self.activityIndicatorView startAnimating]的調用將基本上“標記”activityIndicatorView,以便主線程上的另一個UI函數將啟動它的動畫。 (這就是主要或'UI'線程很重要的原因,因為屏幕上的所有動畫和視覺更新都是相互協調的)。 因此,實際獲取activityIndicator的函數不會被調用,直到initializeArrays完成並且你已經調用了“stopAnimating”。
試試這個:
- (void)viewDidLoad:(BOOL)animated{
[super viewDidLoad];
NSLog(@"viewDidLoad Entered");
[self.activityIndicatorView startAnimating];
partInput.delegate = self;
brandInput.delegate = self;
barcodeInput.delegate = self;
itemNameInput.delegate = self;
}
- (void)viewDidAppear:(BOOL)animated{
//initializeArrays is the function that initializes the arrays
[self initializeArrays];
[self.activityIndicatorView stopAnimating];
}
但是,當您從服務器(或繁重的數據處理)加載東西時,您還必須考慮延遲。 如果將所有網絡通信打包到viewDidLoad或viewWillAppear中 ,它們將在用戶看到視圖之前執行 - 可能導致應用程序的短暫凍結 。 首先向用戶顯示具有某種活動指示符的未填充視圖可能是個好主意。 當您完成網絡時,可能需要一兩秒鍾(或者甚至可能會失敗 - 誰知道?),您可以使用您的數據填充視圖。 在各種Twitter客戶端中可以看到關於如何做到這一點的好例子。 例如,當您在Twitterrific中查看作者詳細信息頁面時,視圖僅顯示“正在加載...”,直到網絡查詢完成。
ViewDidLoad只在您初始化ViewController但每次調用Viewdidapper時調用一次。
僅當主線程(UI線程)不忙時, activityIndicatorViews
才會生成動畫。 viewDidLoad:
和viewDidAppear:
都在主線程上執行。 如上所述,如果initializeArrays
方法不在單獨的線程中執行,那么activityIndicatorViews
將永遠沒有時間進行動畫處理。
View Did Load - 第一種方法,在第一次加載視圖但在屏幕/窗口上沒有出現時調用,僅加載。
只在第一次加載視圖時調用一次。
查看已顯示 - 在調用viewWillAppear后,將調用viewDidAppear。 這意味着視圖現在出現在屏幕上。
用戶從該視圖控制器移動到另一個視圖控制器並返回時調用的次數。
**
**
1)ViewDidLoad(僅在第一次加載視圖時調用),然后2)ViewWillAppear(將被調用次數),然后3)ViewDidAppear(將被調用次數),然后4)ViewWillDisAppear(將被調用的數量為次),然后5)ViewDidDisAppear(將被調用次數)
對於那些以編程方式編碼的(沒有Interface Builder), loadView
是第一個可用的生命周期方法,而不是viewDidLoad
,而編程開發通常比viewDidLoad
更多地使用loadView
,所以請記住這一點。 IB所做的一部分是為您編寫loadView
。 IB只是一種縮短程序開發的方法,但如果你想最好地理解Cocoa Touch,你應該以編程方式理解它。
loadView
是第一個,通常是創建UI元素的地方,包括視圖控制器本身的視圖(編程開發必須明確創建)。 可以在此處添加約束,但直到生命周期的后期才會處理它們。
viewDidLoad
是在建立UI元素后通常進行“邏輯”的地方。
viewWillAppear
和viewWillLayoutSubviews
在UI本身構建自身之前被調用。
viewDidLayoutSubviews
被調用next,可以在實際出現之前在同一個視圖控制器上多次調用。 這是應用自動布局的地方。 這也是程序員可以獲取視圖的安全區域值的地方,因為在此方法之前它們不可用。
視圖控制器的視圖出現在視圖層次結構中后, viewDidAppear
位於最后。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.