Closed jueying-xiangfeng closed 4 years ago
Hi here 👋, what version of FluentDarkModeKit are you using? Can you provide a sample project for us to look at?
你好: 我使用的版本有点老,我们的项目是要适配皮肤,然后是在DarkModeKit基础上做的改动.
开始是 hook 的 UIView
的 setBackgroundColor
方法。后来在使用 [[self appearance] setBackgroundColor:[UIColor redColor]];
的时候会crash,根据旧版的 DarkModeKit 找到的解决方案是这样:
https://stackoverflow.com/questions/42677534/swizzling-on-properties-that-conform-to-ui-appearance-selector
Method method = class_getInstanceMethod(self, @selector(setBackgroundColor:));
dm_original_setBackgroundColor = (void *)method_getImplementation(method);
method_setImplementation(method, (IMP)dm_setBackgroundColor);
static void dm_setBackgroundColor(UIView self, SEL _cmd, UIColor color) {
NSAssert([NSThread isMainThread], @"非主线程修改 UI");
if ([color isKindOfClass:DMDynamicColor.class]) {
self.dm_dynamicBackgroundColor = (DMDynamicColor *)color;
} else {
self.dm_dynamicBackgroundColor = nil;
}
dm_original_setBackgroundColor(self, _cmd, color);
}
然后就会有一定的概率出现上面遇到的crash。
现在用最新的版本 FluentDarkModeKit 的方法:
class_replaceMethod(self, selector, imp_implementationWithBlock(^(UIView self, UIColor backgroundColor) {
if ([backgroundColor isKindOfClass:DMDynamicColor.class]) {
self.dm_dynamicBackgroundColor = (DMDynamicColor *)backgroundColor;
} else {
self.dm_dynamicBackgroundColor = nil;
}
((void (*)(UIView *, SEL, UIColor *))imp)(self, selector, backgroundColor);
}), method_getTypeEncoding(method));
试验了之前会有 crash 的几个机型,没有再出现过crash。
请问下最新版本采用 imp_implementationWithBlock
的方式是基于什么考虑的呢,跟上面提到的 crash 有关系吗?
Interesting, the use of imp_implementationWithBlock
was merely to avoid defining static C functions.
From #30 , we used the approach with C static function in swizzling "setBackgroundColor:" which should have avoided the problem with UIAppearance. @li-bei I recalled that you said that after that PR was merged, some crashes still persist?
好的,谢谢,现在 hook 的时机已经在 APP 启动时就已经完成,目前没有再出现 crash 了。
切换模式的时候遇到crash: 0 libobjc.A.dylib 0x0000000194dfc020 objc_retain + 16 1 UIKitCore 0x00000001995bfaf4 -[UIView+ 15215348 (Hierarchy) _setBackgroundColor:] + 316 2 FDBaseUI 0x000000010661b724 0x1065fc000 + 128804 3 FDADSDK 0x0000000109f75210 0x109f38000 + 250384 4 FDADSDK 0x0000000109f742b0 0x109f38000 + 246448 5 FDADSDK 0x0000000109f72c90 0x109f38000 + 240784 6 FDADSDK 0x0000000109f47a24 0x109f38000 + 64036 7 FDADSDK 0x0000000109fd6f38 0x109f38000 + 651064 8 FDADSDK 0x0000000109fd69e8 0x109f38000 + 649704 9 FDADSDK 0x0000000109fd99a8 0x109f38000 + 661928 10 FDADSDK 0x0000000109f441c0 0x109f38000 + 49600 11 FDADSDK 0x0000000109f43d68 0x109f38000 + 48488 12 FDADSDK 0x0000000109f43b1c 0x109f38000 + 47900 13 FDADSDK 0x0000000109f48a4c 0x109f38000 + 68172 14 FDADSDK 0x0000000109f6a0bc 0x109f38000 + 204988 15 libdispatch.dylib 0x0000000194d86610 _dispatch_call_block_and_release + 24 16 libdispatch.dylib 0x0000000194d87184 _dispatch_client_callout + 16 17 libdispatch.dylib 0x0000000194d39190 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1044 18 CoreFoundation 0x00000001950385e4 CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 12 19 CoreFoundation 0x00000001950335d8 __CFRunLoopRun + 2004 20 CoreFoundation 0x0000000195032adc CFRunLoopRunSpecific + 464 21 GraphicsServices 0x000000019efd3328 GSEventRunModal + 104 22 UIKitCore 0x000000019914063c UIApplicationMain + 1936 23 readerFree 0x0000000105378a88 main + 3771016 (main.m:14) 24 libdyld.dylib 0x0000000194ebc360 start + 4
都是挂在了:static void (dm_original_setBackgroundColor)(UIView , SEL, UIColor *); 看这样子是说当前要修改颜色的view已经销毁了,请问又遇到这种情况吗?