我在 NSMuatableAttributedString 类别中定义了一个方法appendString方法,如下所示:
@implementation NSMutableAttributedString (HTML)
// appends a plain string extending the attributes at this position
- (void)appendString:(NSString *)string
{
NSParameterAssert(string);
NSUInteger length = [self length];
...
而且这个方法在iOS17及之前的版本中效果很好。
但是当iOS18到来的时候。这个appendString不会被调用。
所以我怀疑也许已经有一个系统定义的appendString了。
所以我在空项目中编写了一个演示,以打印 iOS18 中的所有 NSMuatableAttributedString 方法,如下所示:
@interface ViewController ()
@end
@implementation ViewController
void printNSStringCategories() {
unsigned int count;
Class nsStringClass = [NSMutableAttributedString class];
// 获取所有的方法
Method *methods = class_copyMethodList(nsStringClass, &count);
for (unsigned int i = 0; i < count; i++) {
SEL selector = method_getName(methods[i]);
NSString *methodName = NSStringFromSelector(selector);
NSLog(@"NSMutableAttributedString method: %@", methodName);
}
free(methods);
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
printNSStringCategories();
}
并在我的iPhone(iOS18.2)上测试,日志将打印
NSMutableAttributedString method: appendString:withAttributes:
NSMutableAttributedString method: cr_appendStorage:fromRange:
NSMutableAttributedString method: cr_appendString:
NSMutableAttributedString method: appendString:withAttributes:
NSMutableAttributedString method: appendString:
所以看起来
appendString:
已经在系统 SDK 中定义了。
但奇怪的是,当我在 Xcode 模拟器(iOS18.1)中运行这段代码时 这个
appendString:
不会打印。
1 是SDK的bug吗?因为
appendString:
只存在于device-build中,而不存在于simulator-build中?
还有两个问题:
2.1 如果SDK已经包含
appendString:
,为什么我的类别中定义的appendString:
编译时不会出现重复符号错误
2.2 正如问题2.1所说,运行时可能存在相同的符号。有没有办法找到定义这些同名符号的框架/库? (例如:日志中有两个
appendString:withAttributes:
,我想找到两个地方准确定义每个appendString:withAttributes:
)
感谢@Willeke的提示,现在我知道这个问题背后的全部内容了。
正如图像查找 -rn NSMutableAttributedString 所说
appendString
中将会定义一个
ScreenReaderCore framework
ScreenReaderCore`-[NSMutableAttributedString(SCRCMutableAttributedStringExtras) appendString:]
对于问题1:
肯定会有重复的方法! 而且因为这个 ScreenReaderCore 似乎是用于 Voice-Over 的。 模拟器没有使用这个框架。所以这种重复只存在于真实设备中。
对于问题2.1
不同类别中重复的方法编译器无法发现,并且调用的这个函数是未定义的,这是非常危险的,所以最好在类别中的方法名前加上前缀。
对于问题2.2:
正如@Willeke 评论的那样。 运行和暂停应用程序并执行调试器命令
image lookup -rn NSMutableAttributedString or image lookup -rn appendString:. –