(六十九)使用block进行消息传递

在两个类之间进行消息传递,一般通过代理或者block进行,代理写起来较为麻烦,block较为简单,但是block需要特别注意内存泄漏问题,注意self和block之间要为弱引用,下面介绍使用block进行消息传递的方法。

先来复习一下block的结构:

返回类型 (^block名称)(参数1类型,参数2类型...)

下面以XMPP的用户登录为例来说明block消息传递方法。

网络操作在AppDelegate中进行,而登录界面视图控制器类中,由于登录按钮点击之后需要在授权完成时让网络操作类通知登录界面,因此在AppDelegate中定义一个block,并且把它作为登录方法的参数,在登录控制器点击了登录按钮时,必然会调用登录方法,因为登录方法有一个参数是block,因此可以通过这个block实现登录成功后的业务。而AppDelegate只需要在登录方法被调用时把block存起来,在授权成功后调用block,传递参数即可。

具体实现如下:

①在AppDelegate,也就是需要给另一个类传递消息的类内,定义一个block和相应的方法:

typedef enum{
    
    XMPPResultTypeSuccess,
    XMPPResultTypeFailure
    
}XMPPResultType;

typedef void (^XMPPResultBlock)(XMPPResultType type);
/**
 *  用户登录
 */
- (void)xmppUserLogin:(XMPPResultBlock)resultBlock;
②在视图控制器中实现相应方法,传入一个block:

需要注意的是,因为在block中使用了self,会造成block对self的强引用,这个强引用会使得视图控制器在登录结束后无法销毁,从而造成内存泄漏,因此这里使用一个弱指针来调用控制器的方法

AppDelegate *app = [UIApplication sharedApplication].delegate;
    
    __weak typeof (self) selfVc = self; // 弱引用的控制器
    
    [app xmppUserLogin:^(XMPPResultType type) {
        [selfVc handleResult:type]; // 注意block引入了一个对控制器的强引用,无法释放当前控制器,因此应当弱引用
    }];
③在AppDelegate中实现方法时保存传入的block:

@interface AppDelegate () <XMPPStreamDelegate>{
    XMPPResultBlock _resultBlock;
}
- (void)xmppUserLogin:(XMPPResultBlock)resultBlock{
    [self connectToHost];
    _resultBlock = resultBlock;
}
④在授权成功时发送结构,由于block有一个枚举参数,因此可以传入值:

if (_resultBlock) {
    _resultBlock(XMPPResultTypeSuccess);
}
由于_resultBlock保存的正是视图控制器传入的block,因此会在调用时实现视图控制器定义的block的内容。








原文地址:https://www.cnblogs.com/aiwz/p/6154148.html