[IOS]如何使用block来实现回调

一.回调方法总结:

可以参考:https://www.jianshu.com/p/3ff91ef196d1

常用有三种:1.Delegate 和 DataSource 2.Notification 3.Blocks

二.Block

这里重点介绍Block这种用法:

在OC里面是Block,在swift里面叫closure,用法是类似的.

首先OC block简单参考如下:

https://www.jianshu.com/p/7d32ed28292f

这里面实现的是A跳转到B,B处理完,回调数据到A

但是这里面操作的时候有思维上的坑,首先是报野指针的错,然后通过判断是否为空发现,B中的block一直是空的,但是搞不懂为甚是空的.

然后我换了种方法,既然B那里是空的,那我就在A那里传一个block过去,操作如下:

参考:https://www.cnblogs.com/XYQ-208910/p/6257268.html

B.h:

@interface PingInfo : NSObject

- (void) addCallBack:(void(^)(NSString *)) callBackBlock ;

 B.m:

typedef void(^CallBackBlock) (NSString *);

@interface PingInfo()


@end

@implementation PingInfo{
    CallBackBlock _callBackBlock;
}

- (void) addCallBack:(void(^)(NSString *)) callBackBlock {
  
    _callBackBlock = callBackBlock;
    if(_callBackBlock){
        _callBackBlock(@"test-=-=-=-=-=");
        
    }
}

A.swift:

let pingInfo = PingInfo.init()
        
        pingInfo.addCallBack(
            { string in
                print("callback message: \(string)")
            }
        )

Perfect,没有任何问题.可以获得返回数据了.然后我就疑惑,是不是

pingInfo.callBackBlock = { string in
            print("callback message: \(string)")
        }

 这行代码OC不会识别呢,是不是swift和OC之间的处理问题呢,然后我又换了纯swift来试一次回调,参考操作如下:

https://www.jianshu.com/p/20407ee99346

发现B.swift的block还是空的.然后我对照了一下我的代码:

A.swift

pingInfo.passBlock() //错误
pingInfo.callBackBlock = { string in
            print("callback message: \(string)")
        }

B.m:

- (void)passBlock{
    
    if(_callBackBlock == NULL){
        NSLog(@"callBackBlock null ");
    }
    if(_callBackBlock){
        _callBackBlock(@"test-=-=-=-=-=");

    }
}

终于发现了我犯了一个愚蠢的错误.因为网上的参考代码并没有调用B中的方法来实现回调,而是直接跳转处理后回调,一般想法都认为block在B中声明,那么应该是在B中赋值的.其实问题就出现在这里,block应该是在A中赋值的,B中调用的,流程如下:

 OC(B)类里面声明--->swift controller(A)里面赋值----->OC类(B)里面调用------>swift controller(A)获得返回值

因此,我之前的做法直接使用了B类中的block调用,当然是空的,因为并没有执行赋值:

pingInfo.callBackBlock = { string in
            print("callback message: \(string)")
        }

 所以正确的是:

pingInfo.callBackBlock = { string in
            print("callback message: \(string)")
        }
pingInfo.passBlock() //正确

 一般思维惯性都是同一个类里面声明和赋值,但是block好特别,同一个类里面只是声明和调用,打一个比喻,好像买基金,基金的种类和涨跌就是block的声明和调用,但是如果你不买,就是不对一个block赋值(买多少,才知道有多少份额),这只基金是和你无关的,同理,基金涨跌了,对你来说是异步的,结果根据你的赋值(份额)回调(显示)给你就是了.

综上,block有两种操作方式,要不就通过方法来传给B来使用,要不就直接赋值,其实本质都是一样的,和上面的基金例子一样,是否通过代理来买而已.