obj-c编程19:关联对象
2015-06-18 17:25
274 查看
对于一些无法子类化的实例对象来说,如果希望将一个对象与其绑定该如何做呢?
以下示例虚构了一个HyConsoleAlert类,User类将会使用该类在控制台显示定制的告警。如果User中包括多个Alert类则需要手动关联处理每个对应的回调方法,这显得异常麻烦。可以使用objc提供的关联对象模式:将处理例程在生成Alert对象时就与之绑定好,较为漂亮的解决了这个问题。下面上源代码:
以下示例虚构了一个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; }
相关文章推荐
- obj-c编程19:关联对象
- 《开源框架那点事儿16》:缓存相关代码的演变
- obj-c编程19:关联对象
- php -- php缓存技术
- eclipse中使用ant编译时,执行到javac命令后就停止执行解决办法
- 负数的除法和取模运算(Python 2.7和C的比较)
- 最最简单的菜单代码
- NTP服务器搭建
- 设计模式
- SpringMVC介绍之Validation
- 《开源框架那点事儿16》:缓存相关代码的演变
- c#设置IP地址
- Spring启动过程
- asp.net web应用程序不带后缀访问
- a为什么做java的web开发我们会使用struts2,springMVC
- 从Eclipse到Intellij
- 解析java内存原型
- 分享一下eclipse/Myeclipse常用的快捷键
- PYTHON基础
- C++中const顶层指针与底层指针