美文网首页
iOS 属性 代理协议 Block用法

iOS 属性 代理协议 Block用法

作者: GX_Dust | 来源:发表于2016-06-18 09:20 被阅读2035次
    • 前言

    本文用最基本的界面通讯(传个字符串)来举例子, 传递时要分清楚, 控制器出现的先后顺序.(当传递数据时, 下一个界面都没有初始化就肯定不行) 协议和Block不仅可以传递数据, 还可以调用其他页面的函数方法.


    属性传值

    • 例如:第一页内容, 传给后一页
    1. 因为要传递给下一页,  下一页一定要有一个储存的载体, 所以声明一个属性
    @interface SecondViewController ()
    @property (nonatomic, copy)NSString *string;
    @end
    
    2. push下一页时候赋值
    @implementation FirstViewController
    - (void)didClicked:(UIButton *)sender
    {
      SecondViewController *svc = [[SecondViewController alloc]init];
      svc.string = @"苹果"; 
      [self.navigationController pushViewController:svc animated:YES];
    }
    @end
    
    3. 在下一页secondViewController.h中就可以打印出来了
    @implementation SecondViewController
    - (void)viewDidLoad
    {
      [super viewDidLoad];
      NSLog(@"%@", self.string)
    }
    @end
    
    • 优点 最简单的传值方法
    • 缺点 只能从前往后传值

    代理协议

    • 完成协议传值大致分6步
      1. 声明协议
      2. 声明属性 (设置代理人属性)
      3. 执行协议方法 (何时触发方法)
      4. 签协议 (代理人引头文件)
      5. 指定代理人 (.delegate = self)
      6. 实现方法
    • SecondViewController.h
    //在SecondViewController.h中
    //声明协议和代理人的属性
    @protocol secondViewControllerDelegate <NSObject>//第1步
    -(void)passString:(NSString *)string;
    @end
    @interface secondViewController : UIViewController
    //必须是assign,其他会有循环引用问题
    @property (nonatomic, assign)id<secondViewControllerDelegate>delegate;//第2步
    @end
    
    //在SecondViewController.m中
    @implementation secondViewController
    -(void)ViewDidLoad
    {
      //第3步  这个是控制何时触发协议方法的,当程序走到这行代码时,程序会跳转到代理人界面,调用代理人页面下的协议方法
      [self.delegate passString:@"苹果"];
    }
    @end
    
    • FirstViewController.m
    // 引头文件和签协议(必须得有这两步)//第4步
    @interface FirstViewController ()< secondViewControllerDelegate >
    @end
    @implementation FirstViewController
    -(void)ViewDidLoad
    {
    SecondViewController *vc = [[SecondViewController alloc]init];
    vc.delegate = self;//第5步
    //设置的代理人必须是当前的VC!!!!!!!!!!!!!!!!!!!!
    }
    -(void)passString:(NSString *)string//第6步  实现协议方法
    {
        UITextField *textField = [[UITextField alloc]init];
        textField.text = string;//这时string参数就是传过来的"苹果"
    }
    @end
    
    • 优点: 好理解, 最常用的一种设计模式, 可以解决代码的耦合性
    • 缺点: 写的麻烦

    Block传值

    (1). block的写法及分类
    • Block的写法: 返回值类型(^起个名字)(参数类型, 参数类型 *) = ^(参数类型, 参数类型 *){具体实现的方法};
    • Block的四种类型的定义
      • 1.无参数无返回值
         void(^block1)(void) = ^(void){...};
      
      • 2.有参数无返回值
          void(^block2)(int age, NSString *string) = ^(int age, NSString *string)  {...};
      
      • 3.有返回值,无参数
        int (^block3)(void) = ^(void){ return 3; }
      
      • 4.有返回值,有参数
         NSInteger (^block4)(NSInteger *) = ^(NSInteger num) { return num; };
      
    (2).Block传值
    1. 传值页面声明block属性
    //在想要回传的界面中定义,block必须用copy来修饰(*注:SecondViewController.h中声明)
    //@property (nonatomic, copy)NSArray *(^Block)(NSString *string);后面必须两个括号
    @property (nonatomic, copy)void(^Block)(NSString *string);
    
    1. 传值页面调用block, 把"苹果"传过去
    这个就相当于属性的get方法, 会执行- (void(^)(NSString *))Block
    self.Block(@"苹果"); 
    //当程序走到这行代码时,  程序会自动跳转到block内部, 执行下面的方法
    
    1. 被传值的页面block参数就会有值了
    //初始化一个secondVC对象
    SecondViewController *secondVC. = [[SecondViewController alloc]init];
    这个就相当于属性的set方法 会走 - (void)setBlock:(void(^)(NSString *))Block
    secondVC.Block = ^(NSString *string)
    {
            firstVC.label.text = string;
          // 这时string这个参数就是"苹果"了
    };
    //Block与属性区别,  就是可以将代码当参数,  后期调用block时, 被保存的代码就会执行, 跟协议传值大同小异
    

    //关于block的内存问题
    //1.如果要使用block作为一个属性, 必须用copy
    //2.为了防止循环引用, 可以用弱指针代替
    //ARM写法: __weak typeof( 类型 *) weakSelf = self;
    //MRC写法: __ block typeof( 类型 *) weakSelf = self;

    相关文章

      网友评论

          本文标题:iOS 属性 代理协议 Block用法

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