IOS 属性 协议 Block用法

来源:互联网 发布:ios 扑克牌效果源码 编辑:程序博客网 时间:2024/06/11 01:50
  • 前言 

    属性传值是指控制器之间通过定义的属性值来传递( 如字符串.颜色等轻量级的对象), 传递时要分清楚, 控制器出现的先后顺序.
    协议和Block不仅可以传递数据, 还可以调用其他页面的函数方法.


属性传值

  • 例如:第一页textField写什么内容, 后一页textField就显示什么内容
    //首先得在secondViewController.h里面声明一个,公有的属性NSString *,@interface ViewController ()@property (nonatomic, retain)NSString *string;@end
    //在firstViewController中引入secondViewController.h文件,初始化secondViewController *svc = [[secondViewController alloc]init];//初始化textField,让文本框内容等于字符串UITextField *textField = [[UITextField alloc]init];  svc.string = textField.text//此时程序运行到点语法时,程序会跳转到SecondViewController中的公有属性NSString那里, 走里面的setter方法!!!!!!
    //在下一页secondViewController.h中,把textfield赋值  UITextField *textField = [[UITextField alloc]init];  textField.text = self.string;
  • 优点 最简单的传值方法
  • 缺点 只能从前往后传值

协议传值

  • 完成协议传值一共分6步
    1.声明协议
    2.声明属性 (设置代理人属性)
    3.执行协议方法 (何时触发方法)
    4.签协议 (代理人引头文件)
    5.指定代理人 (.delegate = self)
    6.实现方法
  • SecondViewController.h
    //声明协议和代理人的属性@protocol secondViewController <NSObject>//第1步-(void)passString:(NSString *)string;@end@interface secondViewController : UIViewController//必须是assign,其他会有循环引用问题@property (nonatomic, assign)id<wantToDoSomething>delegate;//第2步@end//在SecondViewController.m中@implementation secondViewController-(void)ViewDidLoad{[self.delegate passString:@"苹果"];//第3步  这个是控制何时触发协议方法的,当程序走到这行代码时,程序会跳转到代理人界面,调用代理人页面下的协议方法}@end
  • FirstViewController.m
    @implementation FirstViewController// 引头文件和签协议(前面必须得有这两步)//第4步-(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

  • Block的写法: 返回值类型(^起个名字)(参数类型, 参数类型 ) = ^(参数类型, 参数类型 ){具体实现的方法};
  • Block的四种类型
    1.无参数无返回值
    2.无参数有返回值
    3.有参数无返回值
    4.有参数有返回值
  • 无参数无返回值
    void(^block1)(void) = ^(void){   实现部分   };
  • 有参数无返回值
    void(^block2)(int age, NSString *string) = ^(int age, NSString *string){.............    }block2(20, @"四海八荒");//这个地方给参数
  • 有返回值,无参数
    int (^block3)(void) = ^(void){return 3//必须有return不然抛错.............}block3();//执行block时必须有括号,不管有没有返回值
  • 有返回值,有参数
    NSInteger (^block4)(NSString *) = ^(NSString *string)  {      NSString *str = [string stringByAppendingString:@"34"];      NSInteger number = [str integerValue];//字符串转换整型      return number;  };  NSLog(@"block4 = %ld", block4(@"12"));

Block传值

1.传值页面声明block属性

//在想要回传的界面中定义,block必须用copy来修饰(*注:SecondViewController.h中声明)//@property (nonatomic, copy)NSArray *(^Block)(NSString *string);有返回值的后面必须两个括号@property (nonatomic, copy)void(^Block)(NSString *string);

2.传值页面block装箱操作

self.Block(@"苹果");//所谓装箱,就是把要传递的字符串"苹果"赋值给参数(block参数定义的是字符串)这个也是控制何时触发的,当程序走到这行代码时, 程序会跳转到block内部, 执行方法

3.被传值的页面block卸货操作

//初始化一个secondVC对象SecondViewController *secondVC. = [[SecondViewController alloc]init];secondVC.Block = ^(NSString *string)    {        firstVC.label.text = string;// 这时string这个参数就是字符串"苹果"了    };//Block传值都必须是返传,因为程序经过这段代码时会判断string有没有值, 如果没有就会越过block内部, 如果前一页赋值给string参数, 程序马上就会跳转到block内部中去, 跟协议传值大同小异

//关于block的内存问题
//1.如果要使用block作为一个属性,必须用copy
//2.如果用copy修饰的block中含有"self."都必须使用一个弱引用的指针代替
//ARM写法:  __weak +类型 +指针名 = self;
//MRC写法: __ block +类型 指针名 = self;
//block的内存地址转移(M R C):
//1. 如果block变量内没有使用任何外部变量,block就在全局区
//2. 如果block内部使用了外部变量,block就被转移到栈区
//3.如果block被copy,就被转移到堆区

//block的内存转移(A R C)
//1. 同上
//2.如果block内部使用了外部变量,直接就转移到堆区

0 0
原创粉丝点击