obj-c编程19:关联对象

来源:互联网 发布:flash软件官方下载 编辑:程序博客网 时间:2024/04/30 03:53

对于一些无法子类化的实例对象来说,如果希望将一个对象与其绑定该如何做呢?
以下示例虚构了一个HyConsoleAlert类,User类将会使用该类在控制台显示定制的告警。如果User中包括多个Alert类则需要手动关联处理每个对应的回调方法,这显得异常麻烦。可以使用objc提供的关联对象模式:将处理例程在生成Alert对象时就与之绑定好,较为漂亮的解决了这个问题。下面上源代码:

#import <Foundation/Foundation.h>static void *HyAlertkey = "HyAlertkey";@protocol HyMakeChoose-(void)makeChoose:(NSUInteger)index alertObject:(id)alertObj;@end@interface HyConsoleAlert:NSObject{@private    NSString *_title,*_msg;    id <HyMakeChoose> __weak _delegate;}-(HyConsoleAlert*)initWithTitle:(NSString *) title andMsg:(NSString *) msg    andDelegate:(id <HyMakeChoose>)delegate;-(void)show;@end@implementation HyConsoleAlert-(id)init{    [NSException raise:@"ERR!" format:@"Invalid init method in HyConsoleAlert"];    return nil;}-(HyConsoleAlert*)initWithTitle:(NSString *) title andMsg:(NSString *) msg     andDelegate:(id <HyMakeChoose>) delegate{    self = [super init];    if(self){        _title = [title copy];        _msg = [msg copy];        _delegate = delegate;    }    return self;}-(void)show{    NSLog(@"%@\n%@",_title,_msg);    NSLog(@"Yes or No?");    int c;    while(true){        c = getchar();        NSLog(@"DEBUG:getchar : '%c'",c);        if(c == 'y' || c == 'Y')            c = 1;        else if(c == 'n' || c == 'N')            c = 0;        else            continue;        [_delegate makeChoose:c alertObject:self];        break;          }}@end@interface User:NSObject <HyMakeChoose>{    id _alert;}-(void)askUserQuestion;@end@implementation User-(id)init{    self = [super init];    return self;}-(void)askUserQuestion{    HyConsoleAlert *alert = [[HyConsoleAlert alloc] initWithTitle:@"hopy' question"         andMsg:@"Are you human being"        andDelegate:self];    void (^block)(NSUInteger) = ^(NSUInteger index){        if(index == 1)            NSLog(@"your choose: YES!");        else if(index == 0)            NSLog(@"your choose : NO!");        else            NSLog(@"error!!!");    };    objc_setAssociatedObject(alert,HyAlertkey,block,    OBJC_ASSOCIATION_COPY);    [alert show];}-(void)makeChoose:(NSUInteger)index alertObject:(id)alertObj{    NSLog(@"alertObj is %@",alertObj);    void (^block)(NSUInteger) = objc_getAssociatedObject(alertObj,HyAlertkey);    block(index);/*    if(index == 1)        NSLog(@"your choose: YES!");    else if(index == 0)        NSLog(@"your choose : NO!");    else        NSLog(@"error!!!");*/}@endint main(void){    @autoreleasepool{    /*        User *user = [User new];        HyConsoleAlert *alert = [[HyConsoleAlert alloc]initWithTitle:@"warning"             andMsg:@"Are you human being?" andDelegate:user];        [alert show];    */        User *user = [User new];        [user askUserQuestion];    }    return 0;}
0 0
原创粉丝点击