MacDev 板


LINE

网页版:http://shivahuang.tumblr.com/post/40259924272 问题是这样的,在 OS X 10.8 之前,NSColor 没有办法直接转出 CGColor,所以大家都是自己写 category 补上这个功能。但是在 10.8 Apple 加入了这个 API,而且命名就跟大家习惯的一样,叫做 [aNSColor CGColor]。所以我们可以开心的舍弃掉自己写的 category,采用系统的实 作 - 如果你不管 10.6 和 10.7 的使用者的话… 当然不行。 所以我们还是要保留这个 category,但是我们又希望如果系统有提供这功 能,就采用系统的,如果没有再用 category 里面的实作。这时候可以利用 Obj-C 的一个功能,在呼叫前先用 respondToSelector:(SEL)aSelector 检 查一下他有没有这个 method,所以你可以用像下面一样的做法: if (aColor respondToSelector:@selector(CGColor)]) { [aColor CGColor]; } else { [aColor CGColorFromCategory]; } 但是,这样在程式任何地方要呼叫的时候都要写成这样一串,太麻烦了,而 且容易忘记。而且如果是用旧版的 SDK 编译,Xcode 还会跳出警告,说没 有 CGColor 这个 method。要避免这个 warning 有两个方法,一个是呼叫 的方式改成 [aColor performSelector:@selector(CGColor)],但是直接呼 叫 performSelector: 其实不太好,因为这样 compiler 就完全不会检查有 没有错误…另一个方式是,在 category 里面检查,如果用的是 10.8 之前 的 SDK 编译,就宣告 CGColor 这个 method 让编译器检查。 感觉都很丑… 比较漂亮的做法是,利用 Obj-C 一个比较诡异的功能,叫做 method swizzling。这个功能可以让你在 runtime 的时候,抽换某个类别的底层实 作。我们先看实际的 code 要怎麽做: [ gist: https://gist.github.com/4511790 ] // // NSColor+CGColor.m // // http://stackoverflow.com/questions/11950173/conditional-categories // -in-mountain-lion // #import <objc/runtime.h> static CGColorRef _NSColor_CGColor_(Class self, SEL cmd) { const NSInteger numberOfComponents = [(id)self numberOfComponents]; CGFloat components[numberOfComponents]; CGColorSpaceRef colorSpace = [[(id)self colorSpace] CGColorSpace]; [(id)self getComponents:(CGFloat *)&components]; return (CGColorRef)[(id)CGColorCreate(colorSpace, components) autorelease]; } static NSColor* _NSColor_colorWithCGColor_(Class self, SEL cmd, CGColorRef CGColor) { if (CGColor == NULL) return nil; return [NSColor colorWithCIColor:[CIColor colorWithCGColor:CGColor]]; } __attribute__((constructor)) static void initialize_NSColor_CGColorAdditions() { if (![[NSColor class] respondsToSelector:@selector(colorWithCGColor:)]) { class_addMethod(objc_getMetaClass("NSColor"), @selector(colorWithCGColor:), (IMP)_NSColor_colorWithCGColor_, "@@:@"); } if (![[NSColor class] instancesRespondToSelector:@selector(CGColor)]) { class_addMethod(objc_getClass("NSColor"), @selector(CGColor), (IMP)_NSColor_CGColor_, "@@:"); } } 其中,if (![[NSColor class] instancesRespondToSelector:@selector (CGColor)]) 这行就是在检查 NSColor 有没有实作 CGColor 这个 method,如果没有,就用 class_addMethod(objc_getClass(“NSColor”), @selector(CGColor), (IMP)_NSColor_CGColor_, ”@@:”);把我们自己的 实做加入 NSColor 中。 要加入的实作会放在一个 function 中,至少要接受两个参数 self 和 _ cmd,例如 static CGColorRef _NSColor_CGColor_(Class self, SEL cmd) BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types) 这个 function 则接受四个参数: 1. cls:要加入 method 的 class。 2. name:要加入的 method 的名字。 3. imp:要加入的实作的 function。 4. types:一个用来代表这个 method 参数的字串,第一个是回传值,第二个 是 self,第三个是 cmd,因为第二第三个是固定的,所以字串的第 二第三个一定是 “@:”。以我们 code 中设定的 “@@:” 代表的 是,这个 method 会回传一个 object (id),接收的第一个参数也 是一个 object,第二个参数是一个 selector 的名称。 样就会在系统没有实作 CGColor 这个 method 的时候,把我们自己的实作 插入 NSColor 物件,让我们不管在整个程式的何处都可以放心的直接呼叫 [aColor CGColor]。 -- Luna quieres ser madre y no encuentras querer que te haga mujer --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 112.104.95.143
1F:推 Piceman:赞,学了超强的一招 01/12 00:55
2F:推 wfgh:不能先判断respondToSelector:@selector(CGColor) 01/12 01:21
3F:→ wfgh:再performSelector:@selector(CGColor)吗 01/12 01:22
4F:→ Blueshiva:先判断再呼叫会有几个情形要分别,SDK版本和runtime版本 01/12 01:33







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Tech_Job站内搜寻

TOP