iOS 中delegate与block的转换

in iOS developing with 0 comment

iOS中delegate与block

iOS开发中delegate和block都是用来在对象间进行消息传递的机制,这两种信息传递的方式用的很广泛, 大部分时候这两种方式可以相互转化, 但在设计时两种方式都有各自合适使用的时机。下边举例来说明用两种方式实现同样的效果。
这个例子是让ViewConroller控制器视图背景颜色3s后变色。

delegate实现回调

//DelegateDemo.h (DelegateDemo为协议)
#import <Foundation/Foundation.h>

@protocol DelegateDemo <NSObject>
-(void)updateBackgroundColor;
@end

//ClassA.h(ClassA为委托者)
#import <Foundation/Foundation.h>
#import "DelegateDemo.h"
@interface ClassA : NSObject
@property(nonatomic,weak) id<DelegateDemo> delegate;
-(void)startTheTimer;
@end

//ClassA.m
#import "ClassA.h"

@implementation ClassA
-(void)startTheTimer {
    [NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:@selector(timeProc) userInfo:nil repeats:NO];
}
//回调
-(void)timeProc{
    if([self.delegate respondsToSelector:@selector(updateBackgroundColor)]) {
       [self.delegate updateBackgroundColor];
    }
}
-(void)dealloc {
    NSLog(@"class a dealloc");
}
@end

//ViewController.h (ViewController为代理者)
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end

//ViewConotroller.m
#import "ViewController.h"
#import "DelegateDemo.h"
#import "ClassA.h"

@interface ViewController ()<DelegateDemo>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];    
    //使用代理实现回调
    ClassA *a = [[ClassA alloc] init];
    a.delegate = self;
    [a startTheTimer];//ClassA类通过代理让ViewController类dosomething
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
//实现协议方法
-(void)updateBackgroundColor {
    self.view.backgroundColor = [UIColor redColor];
}
-(void)dealloc {
    NSLog(@"view controller class dealloc");
}

block实现回调

//ClassB.h 
#import <Foundation/Foundation.h>
typedef void (^updateBackgroundColorBlock)(void);
@interface ClassB : NSObject
-(void)startTimerWithBlock:(updateBackgroundColorBlock)block;
@end

//ClassB.m
#import "ClassB.h"

@implementation ClassB

-(void)startTimerWithBlock:(updateBackgroundColorBlock)block {
    [NSThread sleepForTimeInterval:3.0f];
    block();//回调
}
-(void)dealloc {
    NSLog(@"classB dealloc");
}
@end

//ViewController.m
#import "ViewController.h"
#import "ClassB.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //用block实现回调
    ClassB *b = [[ClassB alloc] init];
    NSLog(@"ClassB will be dealloc in 3s");
    [b startTimerWithBlock: ^{
        self.view.backgroundColor = [UIColor greenColor];
    }];
}
-(void)dealloc {
    NSLog(@"view controller class dealloc");
}

delegate与block回调比较

从这两个例子中可以看到这里的场景block回调简洁,逻辑比较清晰, 其中delegate中委托者和代理者之间是N~N(N>=1)的映射关系,即一个委托可以有多个代理,一个代理可以对应多个委托.

st=>start: Start
op=>operation: Your Operation
cond=>condition: Yes or No?
e=>end

st->op->cond
cond(yes)->e
cond(no)->op
评论