iOS 7-viewDidLoad和ViewDidDisplay之间的差异

iOS 7-viewDidLoad和ViewDidDisplay之间的差异,ios,objective-c,Ios,Objective C,抱歉,这本身可能不是一个编程问题,但更多的是对iOS生命周期功能性质的询问 我有一个应用程序,其中有一个函数可以创建四个数组,并通过数据库查询填充它们。首先,我从viewDidLoad函数调用了该函数,但是,每当加载视图时,视图实际出现之前都需要时间(大约3-4秒)。因此,我创建了一个activityViewIndicator,我的viewDidLoad函数如下所示: - (void)viewDidLoad:(BOOL)animated{ [super viewDidLoad];

抱歉,这本身可能不是一个编程问题,但更多的是对iOS生命周期功能性质的询问

我有一个应用程序,其中有一个函数可以创建四个数组,并通过数据库查询填充它们。首先,我从
viewDidLoad
函数调用了该函数,但是,每当加载视图时,视图实际出现之前都需要时间(大约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
之间存在“性能差异”

但是,当您从服务器加载内容(或繁重的数据处理)时,您还必须考虑延迟。如果您将所有网络通信打包到viewdiloadviewwillbeen,则它们将在用户看到视图之前执行-可能导致应用程序的短暂冻结。最好先向用户显示一个带有某种活动指示器的未填充视图。当你完成了你的网络,这可能需要一两秒钟(甚至可能失败-谁知道呢?),你可以用你的数据填充视图。关于如何做到这一点的好例子可以在各种twitter客户端中看到。例如,当您在Twitterrific中查看作者详细信息页面时,视图仅显示“加载…”,直到网络查询完成


初始化ViewController时,ViewDidLoad只调用一次,但Viewdidapper每次都调用一次。

每次请遵循下面的视图控制器生命周期。您将对应用程序以这种方式编写的代码和性能感到惊讶


只有在主线程(UI线程)不忙时,
活动指示器视图才会显示动画<代码>视图加载:
视图显示:
都在主线程上执行。如您所述,如果
initializeArrays
方法没有在单独的线程中执行,然后,ActivityIndicatorView将永远没有时间制作动画。

我将向您介绍苹果的文档,因为我认为需要更多地解释View Controller生命周期,而不仅仅是回答您的问题

最终,视图控制器有一个生命周期:

初始化-但是初始化视图控制器

viewWillLoad/viewDidLoad-在构建视图时调用(通过第一次调用通过视图属性检索视图控制器的UIView-也称为延迟加载)

视图将显示:-当视图准备立即显示(动画==否)或查看转换(动画==是)时

ViewDidDisplay:-如果视图外观未取消且视图控制器的视图完全显示

视图将消失:-补充视图将出现:

ViewDidEnglish:-补充ViewDidEnglish:

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:和ViewDidAspect:之间绝对没有性能差异。这两个函数都是在主线程上运行的正常函数。如果initializeArrays方法需要3秒才能加载,那么无论调用哪个方法都需要3秒。因为您没有显式地更改线程,所以调用initializeArrays的任何函数在完成之前都不会退出

调用[self.activityIndicatorView startAnimating]基本上将“标记”activityIndicatorView,以便主线程上的另一个UI函数将启动它的动画。(这就是为什么主线程或“UI”线程很重要的原因,因为屏幕上的所有动画和视觉更新都在其上进行协调)。因此,在initializeArrays完成并且您已经调用了“stopAnimating”之前,实际运行activityIndicator的函数不会被调用

试试这个:

- (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];
}

视图确实加载了-第一个方法,当视图第一次加载时调用,但不出现在屏幕/窗口上,仅加载

仅在第一次加载视图时调用一次

视图确实出现了-调用ViewWillDisplay后,将调用ViewDidDisplay。这意味着视图现在出现在屏幕上

当用户从该视图控制器移动到另一个视图控制器并返回时调用的次数

**

  • 查看生命周期
**

1) ViewDidLoad(仅在首次加载视图时调用),然后 2) 视图将出现(将被称为次数),然后 3) ViewDid出现(将被称为次数),然后 4) 视图将消失(称为次数),然后
5) ViewDidEnglishe(将被调用多次)

对于那些以编程方式(没有界面生成器)编码的人来说,
loadView
是第一个可用的生命周期方法,而不是
viewDidLoad
,编程开发通常比
viewDidLoad
更多地使用
loadView
,因此请记住这一点。w的一部分