iOS中的代理和Block

一、代理(Delegate)

1)含义

iOS中的代理,比如父母要去上班,到中午12点了,需要给宝宝喂饭吃,但是父母正在上班,这时需要有一个人来帮忙完成一些事情(需要有个保姆来帮忙给宝宝喂饭),此时,保姆就是父母的代理。在中午12点得时候,父母告诉保姆,宝宝该吃饭了,此时,作为代理的保姆,就去给宝宝喂饭。

上面的故事中,保姆就是父母的代理。

2)代理的创建

  • 创建协议

    @protocol DLNameDelegate <NSObject>

  • 声明代理中的方法(@optional和@request)其中有可选实现和必须实现

    @optional

      -(void)fun:(NSString *)str;

    @end

  • 创建Delegate属性

     @property(nonatomic,weak)  id<DLNameDelegate> delegate;

3)代理的使用

在调用代理处理业务时,先判断代理类是否存在且代理类是否实现代理方法

if(self.delegate != nil && [self.delegate respondsToSelector:@selector(fangfaName:)]){
     [self.delegate fangfaName:self];
 
二、block代码块
1)声明
//1.定义无参数无返回值的Block
    void (^printBlock)() = ^(){
        NSLog(@"no number");
    };
    printBlock();

可以看到 block的格式为: 返回值 (^Block名称)(参数类型)  = ^(参数类型 参数名){};

block之所以很好用,是因为block可以作为参数来进行传值或其他操作。

2)声明一个block参数

@property (copy,nonatomic) void (^MyBlock)(NSString *str);

block的属性声明需要用copy,这里稍后我会进行探讨。

typedef void (^MyBlockType)(NSString*);

@property (copy,nonatomic) MyBlockType myBlock2;

这是另一种声明block属性的方式,通过typedef来定义一个别名,通过别名来直接定义block属性。

3)block的使用

线程安全:在调用时需要把Block先赋值给本地变量,以防止Block突然改变。因为如果不这样的话,即便是先判断了Block属性不为空,在调用之前,一旦另一个线程把Block属性设空了,程序就会crash,

 MyBlockType block = self.myBlock2;
    if (block) {
        block(str);
    }

一般情况:

if (self.MyBlock) {
        self.MyBlock(str);
    }

4)示例代码:

- (IBAction)clickblockbtn:(id)sender {
//    MyBlockType block = self.myBlock2;
//    if (block) {
//        block(self.mytf.text);
//        [self dismissViewControllerAnimated:YES completion:nil];
//    }
//    
    if (self.MyBlock) {
        self.MyBlock(self.mytf.text);
    }

}

-(void)clickbtn{

    BViewController *vc = [[BViewController alloc]init];

    vc.delegate = self;

//    vc.MyBlock = ^(NSString *str){

//        self.mainLabel.text = str;

//    };

    vc.myBlock2 = ^(NSString *str){

        self.mainLabel.text = str;

    };

    [self presentViewController:vc animated:YES completion:nil];

}

原文地址:https://www.cnblogs.com/iOSDeng/p/5073686.html