把 Delegate 封装成 Block

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

直接来个UIAlertView做个例子

#import <UIKit/UIKit.h>
#import <objc/runtime.h>

typedef void(^CompletionBlock) (NSInteger buttonIndex);

@interface UIAlertView (Block)

- (void)showAlertViewWithCompletion:(CompletionBlock)completion;

@end
#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);
    }
}
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"Title" message:@"Some Messages" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];

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