3

我的问题似乎需要一位真正有经验的 iOS 开发者的建议。

在我的应用程序中,我实现了一个容器视图控制器(类:CC_CosyLogContainerVC),它由 3 个子视图组成:

  • 带有按钮的标题子视图,用于激活3 个子视图控制器中的 1 个,
  • 一个中间子视图,它显示一些数据和
  • 底部子视图,它是子视图控制器的占位符。

容器视图控制器嵌入在 UINavigationController 中,当它们的子视图控制器变为活动状态时,它也会被它的子视图控制器访问。子视图控制器根据自己的需要设置navigationController 的navigationItem.title 和navigationItem.rightBarButtonItems。

激活和停用子视图控制器的整个管理运行得非常好。没有内存泄漏。

但是我发现了一个性能问题,我用 Instruments 进一步检查了这个问题。也就是说,为什么我现在能够理解这个问题并在这里描述它。不幸的是,我不知道如何解决它!

一开始,当容器视图控制器确实加载时,子视图控制器也非常快速地显示它们的视图。当我在容器的标题子视图中点击一个按钮以切换到另一个子视图控制器时,这种情况发生得非常快 - 但只是在开始时。我发现,每次我做这样的孩子切换,这需要越来越多的时间。

使用我发现的 Instruments,NavigationBar 中的“Button dance”负责这个时间消耗。每次,当其中一个子视图控制器的主视图出现时,它们都会调用一个方法来配置 NavigationBar 的可用按钮。

作为一个典型的例子,我展示了“addCameraButton”的代码:

- (void)addCameraButton
{
    if ((self.cosyLogID) && ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])) {
        if (!self.cameraButtonAdded) {
            //add new Camera Button
            UINavigationItem *myNavigationItem = (self.parentViewController ? self.parentViewController.navigationItem : self.navigationItem);
            NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:myNavigationItem.rightBarButtonItems];
            [newArray addObject:self.cameraButton];
            myNavigationItem.rightBarButtonItems = newArray;
            self.cameraButtonAdded = YES;
        }
    } else {
        //remove old Camera Button if it already exists
        [self removeCameraButton];
    }
}

性能关键的代码行是

        myNavigationItem.rightBarButtonItems = newArray;

Instruments time profiler 显示,这条线占用了整个方法的 99.9%。在 iPhone4 上,第一次调用 [addCameraButton] 需要大约50 毫秒的时间。第二次通话(当我切换到另一个孩子然后切换回这个时)大约需要75 毫秒的时间。

通过广泛的测试和子项之间的手动切换,设置 rightBarButtonItems 数组所需的时间会增长并增长到 500 毫秒甚至更多- 似乎没有限制。

这会导致响应速度变差,因为应用程序变得越来越慢。由于此导航按钮问题,孩子们的视图出现需要越来越多的时间。

如何在设置 rightBarButtonItems 时提供建议和想法,如何解决这个日益增长的时间消耗问题


附加信息:

方法 [removeCameraButton],它是 [addCameraButton] 的对应方法,并在孩子的 [viewWillDisappear] 中调用:

- (void)removeCameraButton
{
UINavigationItem *myNavigationItem = (self.parentViewController ? self.parentViewController.navigationItem : self.navigationItem);
NSArray *oldArray = myNavigationItem.rightBarButtonItems;
NSMutableArray *newArray = [[NSMutableArray alloc] init];
BOOL doAdd;

for (id myObject in oldArray) {
    doAdd = YES;
    if ([myObject isKindOfClass:[UIBarButtonItem class]]) {
        if ([(UIView *)myObject tag] == CC_TAG_FOR_LOGFOTOSVIEW_BTN_CAMERA) {
            doAdd = NO;
        }
    }
    if (doAdd) {
        [newArray addObject:myObject];
    }
}
myNavigationItem.rightBarButtonItems = newArray;
self.cameraButtonAdded = NO;
}

观察 rightBarButtonItems 数组:我确实在调试器中检查了 [newArray count]。它不会随着周期而增长,它肯定总是包含正确数量和种类的 UIBarButtonItems。

相机按钮的Getter 方法

-(UIBarButtonItem *)cameraButton {
if (!_cameraButton) {
    _cameraButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(cameraButtonPressed:)];
    _cameraButton.tag = CC_TAG_FOR_LOGFOTOSVIEW_BTN_CAMERA;
}
return _cameraButton;
}
4

0 回答 0