iOS18中NSMutableAttributedString的appendString方法真机与模拟器差异问询
iOS 18 中 NSMutableAttributedString 分类方法
appendString: 失效问题解答 问题背景
在 NSMutableAttributedString 的分类 HTML 中定义了 appendString: 方法,该方法在 iOS 17 及之前版本运行正常,但升级至 iOS 18 后不再被调用。通过打印 NSMutableAttributedString 的所有方法发现:iOS 18.2 真机中存在系统定义的 appendString: 方法,而 iOS 18.1 模拟器中无此方法。
问题1:这是否属于SDK的bug?
属于苹果SDK的兼容性问题,大概率是bug。原因如下:
- 同一大版本的不同环境(真机/模拟器)API不一致,违反了iOS SDK的环境一致性原则;
- 苹果在iOS 18.2真机中新增了同名方法,但未在SDK头文件中公开,导致开发者的分类方法被系统方法覆盖,且无提前告知,不符合苹果的API变更规范。
问题2.1:若系统已存在appendString:方法,为何我的分类方法未触发编译时重复符号错误?
分类的方法添加逻辑和类的原有方法存在本质区别:
- 系统类的方法存储在类的原生方法列表中,而分类的方法是在运行时动态注入到类的方法列表里的,编译阶段编译器不会检查分类方法和系统类原有方法是否重名;
- 重复符号错误通常出现在两个独立的静态实现(比如两个全局函数重名、同一类的两个非分类扩展实现同名方法),但分类是动态注入逻辑,编译阶段不会触发这类错误,仅在运行时会出现方法覆盖的情况。
问题2.2:如何定位运行时同名方法的定义框架/库?
可以通过两种方式定位:
- LLDB调试命令:
- 在断点处暂停应用,执行
po [NSMutableAttributedString instanceMethodSignatureForSelector:@selector(appendString:)]获取方法签名; - 接着执行
image lookup -s "-[NSMutableAttributedString appendString:]",命令会直接输出该方法所在的二进制文件(框架或库)路径。
- 在断点处暂停应用,执行
- 运行时代码遍历:
编写代码通过运行时API结合动态库信息函数获取模块信息:#import <dlfcn.h> #import <objc/runtime.h> IMP imp = class_getInstanceMethod([NSMutableAttributedString class], @selector(appendString:)); Dl_info info; if (dladdr(imp, &info)) { NSLog(@"方法所在库路径:%s", info.dli_fname); NSLog(@"方法对应符号名:%s", info.dli_sname); }
内容的提问来源于stack exchange,提问作者ximmyxiao
相关产品推荐
相关产品推荐

