使用OC runtime解决第三方库冲突且依赖库版本不同

摘要OC runtime真是一个强大的东西,这次解决了第三方库的冲突问题

前几天在iOS app项目中添加了几个第三方库,各有各的用处,因为一些原因,有些库是不开源的。
添加后,发现app编译不通过,错误如下:

从错误描述中都能看出,app在连接过程中,发现了一些重复的符号,即同样的OC类和方法在不同的库中都有实现:liblibPDRCore.a和libsimpleconfiglib.a这两个库有冲突!恰好,这两个库都要用,而且都不开源,仿佛一下子就走进了死胡同,因为没有办法修改这两个库。
网上搜了一下,碰到这种问题的人还真不少,也提出了解决方案:用lipo命令分解其中一个类,删除重复的符号,再用ar命令重新打包成库,我选择修改liblibPDRCore.a这个库:
1.查看包信息:lipo -info liblibPDRCore.a,提示fat file,那么代表这个包是支持多平台的,例如armv7,armv64等
2.取出armv7包:lipo liblibPDRCore.a -thin armv7 -output armv7/liblibPDRCore_armv7.a
3.解压出object file(.o文件):cd armv7&ar xv liblibPDRCore_armv7.a
4.根据出错信息删除PDRSerAsyncSocket.o:rm PDRSerAsyncSocket.o
5.重新打包:ar rcs liblibPDRCore_armv7.a *.o,记得把旧的库删掉
6.重复1-5把arm64什么的一起改了
7.合并为fat库:lipo -create liblibPDRCore_armv7.a liblibPDRCore_arm64.a -output liblibPDRCore.a
好了,现在用新和成的库替换,并编译,发现编译成功了!
且慢!这和主题OC runtime有什么关系?只是用一些工具去掉了重复符号!
是的,确实没有关系,下面才正式进入主题!
编译是成功了,但实际运行起来呢?非常抱歉,crash了,错误如下:



原因可能是:这两个库虽然有一个名字一样的OC类,有些方法也一样,但并不是完全一样,可以认为,这两个库依赖了另一个开源库,但不是同一个版本,仿佛又走进死胡同鸟!
仔细分析了一些出错信息:liblibPDRCore.a某个地方调用了AsyncSocket类的方法acceptOnAddress:port:error:,但libsimpleconfiglib.a中的AsyncSocket却没有这个方法,造成调用异常。
现在轮到OC runtime上场了,我也只是抱着试一试的态度。前段时间正好看这方面内容,了解到OC可以在运行时动态增加、替换一些类的方法,解决一些实际问题。现在我想到一个思路:用一个空函数,替代AsyncSocket类的方法acceptOnAddress:port:error:,看是否正常运行
1.先获取类类型:Class _asyncSocketClass = NSClassFromString(@"AsyncSocket");
2.给AsyncSocket类添加方法:class_addMethod(_asyncSocketClass, NSSelectorFromString(@"acceptOnAddress:port:error:"), IMP, types);,这个函数中,后面两个参数,一个是替换方法,一个是方法参数类型,替换方法参数好搞,直接定义一个C格式的函数,传函数指针即可;方法参数类型怎么弄?
于是,我想到了从libsimpleconfiglib.a库中找一些蛛丝马迹,虽然它和liblibPDRCore.a使用了不同版本的AsyncSocket类,但某些方法应该是类似的,获取可以帮我完成函数class_addMethod所需的最后一个参数
3.用lipo和ar命令获得libsimpleconfiglib.a中的object file:"AsyncSocket.o"
4.查看"AsyncSocket.o"的导出符号:nm AsyncSocket.o,果不其然,发现一个类似的,方法名不同,参数名却一样



5.再看一下liblibPDRCore.a库中的PDRSerAsyncSocket.o的导出符号,确实有"acceptOnAddress:port:error:"这个方法,我们知道,这个目标文件已经被我们去掉了

6.从名称上判断,这两个方法参数一样,而且方法acceptOnInterface确实存在,用method_getTypeEncoding来获取方法的类型即可得到class_addMethod的最后一个参数,用有了这个思路,完成了如下代码:
<pre><code>

void impfunc(Class cls, SEL _cmd){

if([NSStringFromSelector(_cmd) isEqualtoString:@"acceptOnAddress"]) {

//调用cls的acceptOnInterace的方法 }}- (BOOL)application:...{

Class _asyncSocketClass = NSClassFromString(@"AsyncSocket");

Method _acceptOnInterface = class_getInstanceMethod(_asyncSocketClass, NSSelectorFromString(@"acceptOnInterface:port:error:"));

class_addMethod(_asyncSocketClass, NSSelectorFromString(@"acceptOnAddress:port:error:"),

(IMP)impfunc, method_getTypeEncoding(_acceptOnInterface));

}
</pre></code>

7.编译并运行起来之后,确实走到了impfunc,程序也不崩溃了,但相关的功能不正常,我想还是要真正调用一下acceptOnInterface这个方法才行

8.我想到了解析_cmd的参数,取出参数值,然后再调用objc_msgSend发送消息,尝试了很多方法,没有成功;实际上,我还是走了弯路,各位应该也看出来了,class_addMethod的第三个参数,直接用acceptOnInterface的实现不就行了!method_getImplementation可以帮我们做到,于是代码变成如下,编译后运行,成功了!

- (BOOL)application:...{    

Class _asyncSocketClass = NSClassFromString(@"AsyncSocket");  

  Method _acceptOnInterface = class_getInstanceMethod(_asyncSocketClass,
NSSelectorFromString(@"acceptOnInterface:port:error:"));   

 class_addMethod(_asyncSocketClass,

 NSSelectorFromString(@"acceptOnAddress:port:error:"), 
        
method_getImplementation(_acceptOnInterface ),    

 method_getTypeEncoding(_acceptOnInterface));

}
9.没有了,散会
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容