RTRootNavigationController icon indicating copy to clipboard operation
RTRootNavigationController copied to clipboard

crash & 一点小建议

Open yingpaihuai opened this issue 8 years ago • 7 comments
trafficstars

在push vc的时候crash 堆栈如下,初步发现只在特定的系统ios 10.1.1,自己用相同的系统无法重现,RTContainerNavigationController - viewDidLoad - [self.view layoutIfNeeded]; 崩在这一行了,请问下这里为什么需要手动调用一下layout,去掉后发现横竖屏切换UI异常,是这个原因么,麻烦解答下,3Q。

还有个小问题,在rootnavigationcontroller 中

- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers
                  animated:(BOOL)animated 

中如何设置的是原先就在栈中的vc会重新wrap一遍,导致之前设置的导航栏效果失效(会被重新初始化一遍),改进如下

//fix 如果在栈中已存在的vc 则直接使用原有的container 不重新封装一层
    NSArray *currentVCArr = self.rt_viewControllers;
    NSMutableArray *replaceVCArr = [NSMutableArray array];
    for (int i = 0; i < viewControllers.count ; i++) {
        UIViewController *subVC = [viewControllers objectAtIndex:i];
        if([currentVCArr containsObject:subVC]){
            NSUInteger index = [currentVCArr indexOfObject:subVC];
            UIViewController *orginalContainerVC = [self.viewControllers objectAtIndex:index];
            [replaceVCArr addObject:orginalContainerVC];
        }else{
            [replaceVCArr addObject:subVC];
        }
    }

下面使用replaceVCArr 即可,可以考虑改进下。

Thread 0 Crashed:
0   libobjc.A.dylib                 0x00000001824bef30 objc_msgSend + 16
1   OpenGLES                        0x0000000186090830 +[EAGLContext setCurrentContext:] + 108
2   CoreImage                       0x0000000187764714 __is_gpu_A9_or_higher_block_invoke + 188
3   libdispatch.dylib               0x00000001828fd1c0 _dispatch_client_callout + 16
4   libdispatch.dylib               0x00000001828fdfb4 dispatch_once_f + 56
5   CoreImage                       0x0000000187764650 is_gpu_A9_or_higher + 56
6   CoreImage                       0x000000018774337c CI::GLContext::surface_rowbytes_alignment_for_input+ 336764 (CI::PixelFormat) const + 12
7   CoreImage                       0x0000000187732558 CI::SurfaceNode::surfaceForROI+ 267608 (CI::Context const*, CGRect) const + 124
8   CoreImage                       0x0000000187747958 CI::Context::bind_sampler+ 354648 (CI::TextureSampler const*, CGRect const&, int, CI::KernelArgumentType) + 804
9   CoreImage                       0x0000000187744c64 CI::GLContext::bind_arguments+ 343140 (CI::ProgramNode const*, CGRect const&) + 340
10  CoreImage                       0x00000001877452a4 CI::GLContext::render_intermediate_node(CI::ProgramNode*, CGRect const&, CI::intermediate_t*, void + 344740 () block_pointer) + 520
11  CoreImage                       0x00000001877473bc CI::Context::recursive_render+ 353212 (CI::Node*, CGRect const&, CI::Node*) + 800
12  CoreImage                       0x000000018774725c CI::Context::recursive_render+ 352860 (CI::Node*, CGRect const&, CI::Node*) + 448
13  CoreImage                       0x000000018774725c CI::Context::recursive_render+ 352860 (CI::Node*, CGRect const&, CI::Node*) + 448
14  CoreImage                       0x0000000187747618 CI::Context::render+ 353816 (CI::Node*, CGRect const&) + 88
15  CoreImage                       0x0000000187758e30 invocation function for block in CI::image_get_bitmap+ 425520 (CI::Context*, CI::Image*, CGRect, CGColorSpace*, CI::Bitmap*) + 544
16  CoreImage                       0x000000018775879c CI::tile_node_graph(CI::Context*, char const*, CI::Node*, CGRect const&, CI::PixelFormat, CI::swizzle_info const&, void + 423836 (CI::Node*, CGRect) block_pointer) + 484
17  CoreImage                       0x0000000187757268 CI::image_get_bitmap+ 418408 (CI::Context*, CI::Image*, CGRect, CGColorSpace*, CI::Bitmap*) + 948
18  CoreImage                       0x000000018771782c -[CIContext render:toBitmap:rowBytes:bounds:format:colorSpace:] + 768
19  CoreUI                          0x00000001897074c0 -[CUIShapeEffectStack newFlattenedImageFromShapeCGImage:withScale:ciContext:] + 396
20  CoreUI                          0x000000018970e474 -[CUICatalog imageByStylingImage:stylePresetName:styleConfiguration:foregroundColor:scale:] + 116
21  UIKit                           0x0000000189b937d4 -[UIImage _imageWithStylePresets:withTintColor:] + 628
22  UIKit                           0x00000001898dbbf0 -[UIImageView _setImageViewContents:] + 1368
23  UIKit                           0x00000001898db214 -[UIImageView _updateState] + 644
24  UIKit                           0x00000001898daf68 +[UIView+ 122728 (Animation) performWithoutAnimation:] + 104
25  UIKit                           0x0000000189c68a44 -[UIImageView _updateImageViewForOldImage:newImage:] + 632
26  UIKit                           0x00000001898da8d4 -[UIImageView setImage:] + 352
27  UIKit                           0x0000000189dc27b0 -[UIButton _updateImageView] + 176
28  UIKit                           0x0000000189922674 -[UIButton layoutSubviews] + 192
29  UIKit                           0x00000001898ca220 -[UIView+ 53792 (CALayerDelegate) layoutSublayersOfLayer:] + 1196
30  QuartzCore                      0x0000000186d8a188 -[CALayer layoutSublayers] + 148
31  QuartzCore                      0x0000000186d7ee64 CA::Layer::layout_if_needed+ 1093220 (CA::Transaction*) + 292
32  UIKit                           0x00000001898dec90 -[UIView+ 138384 (Hierarchy) layoutBelowIfNeeded] + 1020
33  bigoshow                        0x00000001000550a8 -[RTContainerNavigationController viewDidLoad] + 118952 (BVRootNavigationController.m:394)
34  UIKit                           0x00000001898cd0b0 -[UIViewController loadViewIfRequired] + 1056
35  UIKit                           0x00000001898ccc78 -[UIViewController view] + 28
36  bigoshow                        0x0000000100053cb0 -[RTContainerController viewDidLoad] + 113840 (BVRootNavigationController.m:226)
37  UIKit                           0x00000001898cd0b0 -[UIViewController loadViewIfRequired] + 1056
38  UIKit                           0x00000001898ccc78 -[UIViewController view] + 28
39  bigoshow                        0x000000010005813c -[BVRootNavigationController setGestureRecognizerWithViewController:] + 131388 (BVRootNavigationController.m:945)
40  bigoshow                        0x0000000100057fd4 -[BVRootNavigationController pushViewController:animated:] + 131028 (BVRootNavigationController.m:924)
41  bigoshow                        0x00000001000556bc -[RTContainerNavigationController pushViewController:animated:] + 120508 

yingpaihuai avatar Nov 23 '17 04:11 yingpaihuai

这个 crash 貌似是你自己的业务代码产生的,查看下 opengl 相关的使用?

setViewControllers:animated: 确实是用法不好理解

rickytan avatar Nov 23 '17 13:11 rickytan

- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers
                  animated:(BOOL)animated
{
    [super setViewControllers:[viewControllers rt_map:^id(__kindof UIViewController * obj,  NSUInteger index) {
        if (self.useSystemBackBarButtonItem && index > 0) {
            return RTSafeWrapViewController(obj,
                                            obj.rt_navigationBarClass,
                                            self.useSystemBackBarButtonItem,
                                            viewControllers[index - 1].navigationItem.backBarButtonItem,
                                            viewControllers[index - 1].title);
        }
        else
            return RTSafeWrapViewController(obj, obj.rt_navigationBarClass);
    }]
                     animated:animated];
}

原代码是 RTSafeWrapViewController,所以参数 viewControllers 应当通过 self.rt_navigationController.viewControllers 获取,而不是 self.rt_navigationController.rt_viewControllers 获取,这样就不会有问题

rickytan avatar Nov 23 '17 13:11 rickytan

不重新 wrap 会产生新问题,返回按钮上的字会不正确,如栈中已经有: VC1 => title1 VC2 => title2 VC3 => title3

然后 [self.navigationController setViewControllers:@[VC1, VC3] animated:YES],这时 VC3 上的返回按钮可能还是 title2,但应该是 title1 了(在 useSystemBackBarButtonItem = YES 的情况下)

rickytan avatar Nov 23 '17 14:11 rickytan

因为在日常使用过程中,需要对堆栈的vc做出处理,比如需要找到某个特定的vc,然后移除之后添加下一个vc。 前:[vc3,vc2,vc1] 后:[vc4,vc2,vc1] --- 这里的vc都是没有wrap的。 如果使用 self.rt_navigationController.viewControllers 来获取,则需要在拿一下contentViewcontroller(方便判断class类型),对于使用者来说不符合预期。

我加的那个判断就是防止这种情况(因为你无法强调使用者在setviewcontrollers中传的到底是什么类型),因为这个数组中完全有可能是掺杂着wrap过和没有wrap的。在传入的是unwrap后的vc,而且这个vc本身已经存在在viewcontrollers中,则手动把它替换成wrap后的(防止被重新wrap),我觉得这种操作是对使用者友好的。

如果每次都重新wrap,那么在set的时候就会把vc1重新wrap一下,比如我在vc1的viewdidload中有做一些对导航栏的初始化操作,那么就不会执行了(因为重新wrap并不会重新viewdidload,这是显然也符合预期的)。

还有一点是我并没有使用这个api相关导航栏的操作,我是自己封装的,使用这个框架最想解决的问题是每个vc独立的navbar。所以楼主提到的返回title问题可能没有了解过。

至于那个崩溃确实也是比较奇怪,因为单纯的 [EAGLContext setCurrentContext:] 崩溃在这一行确实让人找不到原因,这里问一下主要目的可能是想问一下作者的产品是否有类似的问题,所以提出来了。(之前的版本是没有这个崩溃的)。

最后还有一个问题是,RTContainerNavigationController 中是否做一下presentViewController,dismissViewControllerAnimated的消息转发,因为在日常使用过程中会出现present 一个 rtrootnavvc的情况,但是在dismiss调用的是否我们往往的self.navigationController dismiss...,这也是pushvc转发的原因吧。如果使用者重写了dismiss,并在其中做了某些处理,直接通过[self.navigationController dismiss...]则并不会调用到rootnavvc的dismiss了。

yingpaihuai avatar Nov 24 '17 02:11 yingpaihuai

返回的 title 修改应该可以不重新 wrap 实现,这个问题后面有空再看。

dismiss 的问题你其实可以直接 [self dismissViewController...],不过也算个问题

rickytan avatar Nov 24 '17 04:11 rickytan

有空帮助测试下分支 https://github.com/rickytan/RTRootNavigationController/tree/issue158 有没有解决你的问题

rickytan avatar Feb 11 '18 05:02 rickytan

上面说的崩溃解决了吗?怎么解决的可以说以一下吗?谢谢

lqwang521 avatar Jun 28 '19 03:06 lqwang521