美文网首页
三个VC间跨页面逆向传值之代理传递

三个VC间跨页面逆向传值之代理传递

作者: boyka_yang | 来源:发表于2019-04-18 18:35 被阅读0次
    做iOS开发应该都头疼过这样一个问题:跨页面回调数据!

    假设有这样一个场景:
    三个viewController依次被push出来,简称A、B、C三个页面。
    其实C页面的操作会影响A页面的某项展示,而push出的页面,正常情况下我们会一级级pop回去,当我们pop两次之后回到A的时候发现数据还是原始数据,这肯定是不太友好的。那么我们就需要知道在C页面进行了什么骚操作,进行必要的更新。要么拉取服务端数据要么改值,终归要知道C页面里做没做,此时我们可以用 通知 进行传值,可以跨多层直到目标,但是一个较大的项目中若滥用通知的话视乎有点可耻。

    还有另外两种方式:代理 block。但是跨页面的时候难免会有这么一层传递。
    🌰例如:

    // C 页面这么写
    - (void)XXXX事件:(id)sender{
      if (self.delegate && [self.delegate respondsToSelector:@selector(XXXX代理方法:)]) {
            [self.delegate XXXX代理方法:obj];
        }
    }
    
    // B页面自己再声明一个protocol,并声明一个属性  同时遵守C声明的协议并实其delegate方法
    - (void)C页面代理方法:(id)obj{
    // 在C页面的代理方法里调自己的代理方法
      if (self.delegate && [self.delegate respondsToSelector:@selector(XXXX代理方法:)]) {
            [self.delegate XXXX代理方法:obj];
        }
    }
    
    // A页面遵守B协议并实现代理
    - (void)B页面代理方法:(id)obj{
    // 拿到C回调过来的值 进行一些处理
      
    }
    

    🔥如此一套下来,总看着B页面里的delegate那么多余,就做了如下设想:
    既然目的只是让A拿到C的回调,那么我是否可以不在B里声明一套自己协议呢?做了如下尝试:

    C页面.h头文件

    #import <UIKit/UIKit.h>
    
    @protocol testDelegateTransition <NSObject>
    - (void)callBackSomeContent:(id)obj;
    @end
    
    @interface ViewControllerC : UIViewController
    @property (nonatomic, weak) id <testDelegateTransition> delegate;
    @end
    

    B页面.h文件

    #import <UIKit/UIKit.h>
    // 为了引用C页面的testDelegateTransition   只能先import其头文件
    #import "ViewControllerC.h"
    
    @interface ViewControllerB : UIViewController
    @property (nonatomic, weak) id <testDelegateTransition> delegate;
    @end
    

    B页面.m实现文件

    @implementation TestTransDelegateVCB
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.navigationItem.title = @"代理传递的中专页面";
        self.view.backgroundColor = [UIColor purpleColor];
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        TestTransDelegateVCD *vc = [[TestTransDelegateVCD alloc] init];
        vc.delegate = self.delegateB;
        [self.navigationController pushViewController:vc animated:YES];
    }
    @end
    

    VCA的.m文件

    #import "ViewControllerA.h"
    #import "ViewControllerB.h"
    
    
    
    @interface ViewControllerA ()<testDelegateTransition>
    
    @end
    
    @implementation TestTransDelegateVCA
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.navigationItem.title = @"测试代理传递";
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        ViewControllerB *vc = [[ViewControllerB alloc] init];
        vc.delegateB = self;
        [self.navigationController pushViewController:vc animated:YES];
    }
    
    // C页面的代理方法
    - (void)callBackSomeContent:(id)obj{
        
    }
    @end
    

    😊很开心,此次尝试成功的,说明想法没问题,也没有影响VC的释放。那么有没有别的问题呢?🎈还是有点的,比如没必要在VCB的.h头文件里就导入C。接着进行点整理,把delegate声明相关放在创建的单独的头文件。

    #ifndef TestTransitionDelegateHeader_h
    #define TestTransitionDelegateHeader_h
    
    @protocol testDelegateTransition <NSObject>
    - (void)callBackAContent:(NSString *)c;
    @end
    
    #endif /* TestTransitionDelegateHeader_h */
    

    这样,因为需要访问这个delegate而导入的ViewControllerC就可以省掉,转而导入TestTransitionDelegateHeader_h这个头文件。

    这一次设想到此就验证结束了,涉及的7个文件可以到 这里 查看。里边有我所有的猜想验证、demo、小测试。

    🤣说了半天废话其实就这么一句话:"简化了 B页面里边,声明自己协议 遵守C协议并实现方法 ";

    本文的直达传送门
    所属demo传送门

    相关文章

      网友评论

          本文标题:三个VC间跨页面逆向传值之代理传递

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