把 Delegate 封装成 Block

UIAlertView和UIActionSheet之类的控件只支持Delegate方式作为回调,但是这样小的操作要把代码分散开来就很不爽了~因此有了BlocksKit这个第三方开源扩展库,但是如果要自己封装一个的话也未免不可~主要是用到了关联来扩展了它们的属性。

直接来个UIAlertView做个例子

1
2
3
4
5
6
7
8
9
10
#import <UIKit/UIKit.h>
#import <objc/runtime.h>

typedef void(^CompletionBlock) (NSInteger buttonIndex);

@interface UIAlertView (Block)

- (void)showAlertViewWithCompletion:(CompletionBlock)completion;

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#import "UIAlertView+Block.h"

@implementation UIAlertView (Block)

static const char AlertViewCompletionKey;

- (void)showAlertViewWithCompletion:(CompletionBlock)completion
{
if (completion) {
objc_removeAssociatedObjects(self);
objc_setAssociatedObject(self, &AlertViewCompletionKey, block, OBJC_ASSOCIATION_COPY); //每一个关联的关键字必须是唯一的。通常都是会采用静态变量来作为关键字。
self.delegate = self;
}
[self show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
CompleteBlock completionBlock = objc_getAssociatedObject(self, &AlertViewCompletionKey);
if (completionBlock) {
completionBlock(buttonIndex);
}
}
1
2
3
4
5
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"Title" message:@"Some Messages" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];

[alert showAlertViewWithCompletion:^(NSInteger buttonIndex) {
NSLog(@"Selected Button Index = %d", buttonIndex);
}];