obj-c编程19:关联对象

对于一些无法子类化的实例对象来说,如果希望将一个对象与其绑定该如何做呢?
以下示例虚构了一个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!!!");
*/
}
@end

int 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大熊猫侯佩

赏点钱让我买杯可乐好吗 ;)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值