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;
}
obj-c编程19:关联对象的更多相关文章
- 并发编程 19—— 显式的Conditon 对象
Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...
- 13_Python的面向对象编程-类class,对象object,实例instance
1.面向对象概述 1.类是用来描述对象的工具,把拥有相同属性和行为的对象分为一组 2.对象是由类实例化出来的一个具体的对象 属性: 对象拥有的名词,用变量表示 ...
- 关联对象 AssociatedObject 完全解析
我们在 iOS 开发中经常需要使用分类(Category),为已经存在的类添加属性的需求,但是使用 @property 并不能在分类中正确创建实例变量和存取方法. 不过,通过 Objective-C ...
- Python记录14:面向对象编程 类和对象
'''现在主流的编程思想有两种,一种是面向对象,一种是面向过程面向过程编程 核心是过程二字,过程指的是解决问题的步骤,即先干什么.再干什么.最后干什么... 基于该思想编写程序就好比再设计一条流水线, ...
- Runtime之成员变量&属性&关联对象
上篇介绍了Runtime类和对象的相关知识点,在4.5和4.6小节,也介绍了成员变量和属性的一些方法应用.本篇将讨论实现细节的相关内容. 在讨论之前,我们先来介绍一个很冷僻但又很有用的一个关键字:@e ...
- admin.ModelAdmin 后台管理关联对象,某个字段怎么显示值
admin.ModelAdmin 后台管理关联对象,某个字段如何显示值?对象 WxpAccount: accountName = ... 对象 AccountMenu: ...
- Runtime - Associated Objects (关联对象) 的实现原理
主要围绕3个方面说明runtime-Associated Objects (关联对象) 1. 使用场景 2.如何使用 3.底层实现 3.1 实现原理 3.2 关联对象被存储在什么地方,是不是存放在被 ...
- Django 08 Django模型基础3(关系表的数据操作、表关联对象的访问、多表查询、聚合、分组、F、Q查询)
Django 08 Django模型基础3(关系表的数据操作.表关联对象的访问.多表查询.聚合.分组.F.Q查询) 一.关系表的数据操作 #为了能方便学习,我们进入项目的idle中去执行我们的操作,通 ...
- JS面向对像编程四—— prototype 对象
http://blog.csdn.net/fanwenjieok/article/details/54575560 大部分面向对象的编程语言,都是以“类”(class)作为对象体系的语法基础.Java ...
随机推荐
- 关于React Native 安卓首屏白屏优化
问题描述 在android中,当点击某个rn模块的入口按钮,弹出rn的activity到rn的页面展现出来的过程中,会有很明显的白屏现象,不同的机型不同(cpu好的白屏时间短),大概1s到2s的时间. ...
- JRE System Library [JavaSE-1.7](unbound)
window > preferences > java > Install jars >如果没有jdk1.7 ,点击下面的search,会自动找到已经安装对jdk1.7,选择, ...
- Servlet概述-servlet学习之旅(一)
Servlet概述 servlet是server+applet的缩写.applet是运行于客户端浏览器的java小程序,java诞生的时候,因为applet而闻名于世,但是现在已经没有多少热使用了,而 ...
- Android4.4.2KK竖屏强制更改为横屏的初步简略方案
点击打开链接 解决方案: 当前是根据当前问题场景即竖屏强制更改为横屏的需求而做的改动,基本是hardcode定义的状态,总共修改有效代码行数5行,如果后续有其他需求或者需要更灵活的配置横屏和竖屏,可以 ...
- 如何在Cocos2D游戏中实现A*寻路算法(七)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
- JSP实现界面的自动跳转的几种方式
下面来谈一谈在jsp中实现的几种界面自动跳转的方法. 使用JavaScript脚本 <html> <script language=javascript> function o ...
- Cocos2D:塔防游戏制作之旅(三)
整合炮塔资源 为了快速开始,我们为你创建了开始的项目.它包括了一个空白的Cocos2D项目以及大多数你将在教程中使用到的资源. 所以首先下载该 开始项目 并且解压缩到你指定的位置中去. 注意:该项目的 ...
- 使用WakeLock使Android应用程序保持后台唤醒
在使用一些产品列如微信.QQ之类的,如果有新消息来时,手机屏幕即使在锁屏状态下也会亮起并提示声音,这时用户就知道有新消息来临了.但是,一般情况下手机锁屏后,Android系统为了省电以及减少CP ...
- 【Unity Shaders】概述及Diffuse Shading介绍
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- (NO.00002)iOS游戏精灵战争雏形(五)
完成了精灵自己移动之后,我们开始着手实现按住精灵拖动的功能. 要想处理触摸事件,我们需要做2件事: 1.在类的初始化中打开触摸接收属性 2.实现触摸处理回调方法 我们依次来做这2件事. 首先要搞清楚在 ...