把 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);
}];