http://www.devdiv.com/%E4%BF%AE%E6%94%B9%E7%88%B6%E7%B1%BB%E5%B7%B2%E7%BB%8F%E5%AD%98%E5%9C%A8%E7%9A%84%E6%96%B9%E6%B3%95_%E6%B7%BB%E5%8A%A0%E8%87%AA%E5%B7%B1%E7%9A%84%E5%A4%84%E7%90%86%E6%B5%81%E7%A8%8B%E6%88%96%E8%80%85%E7%9B%B4%E6%8E%A5%E9%87%8D%E5%86%99_%EF%BC%8C%E6%AF%94category%E6%9B%B4%E7%8A%80%E5%88%A9-article-1644-1.html
摘要: 第一帖,实在想不到好一点的标题来表达这么劲爆的内容。 前两天看Safari AdBlock源码的时候学到的,觉得比较犀利,也比较实用。 category大家肯定都熟(不熟悉的请学好Objective-C基础教程),可以为已有类型创建 ...
第一帖,实在想不到好一点的标题来表达这么劲爆的内容。
前两天看Safari AdBlock源码的时候学到的,觉得比较犀利,也比较实用。
category大家肯定都熟(不熟悉的请学好Objective-C基础教程),可以为已有类型创建自己独有的类别,往里面添加自定义的方法来迎合实际需求。 但是,如果想修改已经存在的方法怎么办? 这里说一下两种情况: 1. 完全覆盖,这个好说,继承一下,把接口重写就好了。 2. 部分修改,例如增加自己的处理流程。你肯定讲继承一样可以做到,但是我们千万不能忘记category为什么要存在。
下面就以NSString(大家肯定清楚用继承对这个类进行扩展的弊端吧)举个简单的例子: 1. 目的: 修改UTF8String这个方法,当我们通过这个方法获取C字符串的时候,在源串后面添加"^_^DevDiv"。
2. 实现: 2.1 首先为NSString创建一个类别,定义如下
- @interface NSString (NSString_Addition)
- + (BOOL)swizze;
- @end
复制代码
2.2 实现静态方法swizze,移花接木的本事就在下面的代码里了
- + (BOOL)swizze
- {
- Method oldMethod = class_getInstanceMethod(self, NSSelectorFromString(@"UTF8String"));
- if (!oldMethod)
- {
- return NO;
- }
- 2.3 做我们想做的事情
- [code]- (const char *)ovUTF8String
- {
- NSLog(@"in:ovUTF8String");
-
- char *sOriginal = (char *)[self ovUTF8String]; // endless recursion?? no.
- // look up the definition of swizze
- int iOrgLen = (NULL == sOriginal ? 0 : strlen(sOriginal));
-
- char *sCustom = (char *)malloc(iOrgLen + strlen(CSTRING_CUSTOM_ADDITON) + 1);
- if (NULL != sCustom)
- {
- NSLog(@"alloc mem for custom string succeed!");
-
- if (NULL != sOriginal)
- {
- strcpy(sCustom, sOriginal);
- }
-
- strcat(sCustom, CSTRING_CUSTOM_ADDITON); // CSTRING_CUSTOM_ADDITON == "^_^DevDiv"
- }
-
- NSLog(@"out:ovUTF8String");
-
- return (const char *)sCustom;
- }
复制代码
2.4 测试一下
- if ([NSString swizze])
- {
- NSLog(@"swizze succeed!");
-
- NSString *s1 = @"Hello, everyone";
-
- NSLog(@"original:%@", s1);
-
- char *s2 = (char *)[s1 UTF8String];
-
- NSLog(@"new:%s", s2);
- }
复制代码
2.5 运行结果
|