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

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

先来复习一下block的结构:

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

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

网络操作在AppDelegate中进行,而登录界面视图控制器类中。由于登录button点击之后须要在授权完毕时让网络操作类通知登录界面,因此在AppDelegate中定义一个block,而且把它作为登录方法的參数。在登录控制器点击了登录button时。必定会调用登录方法,由于登录方法有一个參数是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/jhcelue/p/6774458.html