美文网首页iOS常用
iOS 项目中自定义UITabBarController使用过程

iOS 项目中自定义UITabBarController使用过程

作者: 爱在心_001 | 来源:发表于2021-08-03 10:54 被阅读0次

    UITabBarController作为一个集合视图控制器,在很多APP上面都会用到,当app中有多个控制器的时候,就需要对这些控制器进行管理,用一个控制器去管理其他多个控制器。如图所示:


    1501570714806185.png

    再使用的过程中我的项目中使用方式是
    自定义TabBarController

    //首页
        HomePageViewController      *homeVC    = [[HomePageViewController alloc] init];
        UIViewController     *testVC   = [[UIViewController alloc] init];
        [self addChildViewController:homeVC title:@"首页" imageName:@"tabBar_icon_home_normal" selectImageName:@"tabBar_icon_home_selected"];
        [self addChildViewController:applyVC title:@"test" imageName:@"tabBar_icon_test_normal" selectImageName:@"tabBar_icon_test_selected"];
    
    //添加子控制器
    - (void)addChildViewController:(UIViewController *)childController title:(NSString *)title imageName:(NSString *)imageName selectImageName:(NSString *)selectImageName {
        //设置标题
        childController.title = title;
        UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",imageName]];
        childController.tabBarItem.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];;
        
        UIImage * selectedImage = [UIImage imageNamed:[NSString stringWithFormat:@"%@",selectImageName]];
        childController.tabBarItem.selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
        UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:childController];
        [self addChildViewController:nav];
    
    }
    

    在登录成功之后,进入主页

      TZTabBarController * tabBarController = [[TZTabBarController alloc] init];
      [UIApplication sharedApplication].keyWindow.rootViewController = tabBarController;
    

    而HomePageViewController类里也实现

    - (void)dealloc {
        NSLog(@"%@ --- dealloc",self);
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    

    然而我在HomePageViewController的viewDidLoad里注册了通知,然后我重新登录操作,就发现了异常,仔细看没有其他地方注册这个通知,却出现通知两次。

    - (void)viewDidLoad {
        [super viewDidLoad];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshMyDataNoti) name:@"RefreshRouteListNotice" object:nil];
    }
    

    经过排查由于之前的HomePageViewController的viewDidLoad里的通知没有被释放。导致通知注册了两次,可想而知如果我继续退出登录操作通知还会继续注册下去,因此我对在登录成功之后,进入主页进行了改善,

    AppDelegate * app = (AppDelegate *)[UIApplication sharedApplication].delegate;
            [app buildTabBarController];
            [app setSelectTabPage:0];
    

    在AppDelegate里懒加载自定义TabBarController,然后重新赋值给 [UIApplication sharedApplication].keyWindow.rootViewController便能解决再次触发HomePageViewController的viewDidLoad方法。

    - (void)setSelectTabPage:(NSInteger)index {
            self.tabBarController.selectedIndex = index;
    }
    

    但是上述方法也会出现tabbar一级页面刷新不及时的问题,因此这么使用的时候需要注意每个tabbar一级页面的刷新问题。

    现在我们来深入思考下为什么不能在dealloc中调用
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    在我们想添加观察者的时候,我们观察者的retainCount被引用计数+1了吗?
    如果没有被引用计数+1,那么当这个类会在retainCount为0时被销毁,通知中心就无法通知到该类,那么remove方法还有意义吗?
    所以在添加观察者的时候,通知中心必然会将该观察者的retainCount+1,
    既然通知中心retain了这个观察者,那么很不幸,这个观察者的dealloc方法永远不会被调用,他的retainCount最少也是1,因为通知中心retain了一次,结果 
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    就永远不被调用。
    
    

    如果您有其他的解决方案,欢迎留言一起交流,相互学习。

    相关文章

      网友评论

        本文标题:iOS 项目中自定义UITabBarController使用过程

        本文链接:https://www.haomeiwen.com/subject/zhgsvltx.html