菜鸟教程小白 发表于 2022-12-13 00:05:03

ios - Swizzling 符合 UI_APPEARANCE_SELECTOR 的属性


                                            <p>我正在尝试调整 UIView 上的 backgroundColor 属性。<br><br>在我调酒之前,我执行以下操作:<br><pre><code>@implementation UIView (Cat1)
+(void)load {
NSArray *selectors = @[
                     //Highliter swizzling
                     NSStringFromSelector(@selector(setBackgroundColor:)),
                     NSStringFromSelector(@selector(backgroundColor))
                     ];

[ setBackgroundColor:];

for (NSString *name in selectors) {
    SEL originalSelector = NSSelectorFromString(name);
    SEL swizzledSelector = NSSelectorFromString();
    Method originalMethod = class_getInstanceMethod(self, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
    class_addMethod(self,
                  originalSelector,
                  class_getMethodImplementation(self, originalSelector),
                  method_getTypeEncoding(originalMethod));
    class_addMethod(self,
                  swizzledSelector,
                  class_getMethodImplementation(self, swizzledSelector),
                  method_getTypeEncoding(swizzledMethod));
    method_exchangeImplementations(originalMethod, swizzledMethod);
}
</code></pre><br>然后,当调用 swizzled 方法时,除了调用原始方法之外,我什么都不做:<br><pre><code>-(void)swizzled_setBackgroundColor:(UIColor *)color {

;
}
</code></pre><br>然后,发生以下崩溃:<code>2017-03-08 19:04:37.863 Develop-InsertViewer *** Terminating app due to uncaught exception &#39;NSInternalInconsistencyException&#39;, reason: &#39;Please file a radar on UIKit if you see this assertion.&#39;
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000108506e65 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x0000000107c7ddeb objc_exception_throw + 48
    2   CoreFoundation                      0x0000000108506cca + + 106
    3   Foundation                        0x00000001078ca5a2 - + 169
    4   UIKit                               0x0000000106227b35 PushNextClassForSettingIMP + 469
    5   UIKit                               0x000000010622810a TaggingAppearanceObjectSetterIMP + 37
    6   InsertFramework                     0x00000001071332be - + 62
    7   UIKit                               0x0000000105d78fca - + 238
    8   UIKit                               0x0000000105d7913d - + 94
    9   UIKit                               0x0000000105b9cc4e - + 62
    10                  0x0000000105533300 _TTOFCSo7UILabelcfT_S_ + 16
    11                  0x0000000105532e44 _TFCSo7UILabelCfT_S_ + 68
    12               0x0000000105569be3 _TFC12InsertViewer21StarterViewControllercfT5coderCSo7NSCoder_GSqS0__ + 51
    13                  0x0000000105569d2d _TToFC12InsertViewer21StarterViewControllercfT5coderCSo7NSCoder_GSqS0__ + 45
    14UIKit                               0x0000000105ecb7db - + 241
    15UIKit                               0x000000010609f822 UINibDecoderDecodeObjectForValue + 705
    16UIKit                               0x000000010609f558 - + 278
    17UIKit                               0x0000000105ecb4b1 - + 180
    18UIKit                               0x000000010609f822 UINibDecoderDecodeObjectForValue + 705
    19UIKit                               0x000000010609f9e3 UINibDecoderDecodeObjectForValue + 1154
    20UIKit                               0x000000010609f558 - + 278
    21UIKit                               0x0000000105eca6c3 - + 1255
    22UIKit                               0x0000000106232c40 - + 181
    23UIKit                               0x0000000106232d93 - + 69
    24UIKit                               0x0000000105b0dfa6 - + 94
    25UIKit                               0x0000000105b0e2d6 - + 260
    26UIKit                               0x0000000105b0cb54 - + 1390
    27UIKit                               0x0000000105b09e7b - + 188
    28FrontBoardServices                  0x000000010b41e754 - + 192
    29FrontBoardServices                  0x000000010b41eac2 - + 45
    30CoreFoundation                      0x0000000108432a31 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    31CoreFoundation                      0x000000010842895c __CFRunLoopDoSources0 + 556
    32CoreFoundation                      0x0000000108427e13 __CFRunLoopRun + 867
    33CoreFoundation                      0x0000000108427828 CFRunLoopRunSpecific + 488
    34UIKit                               0x0000000105b097cd - + 402
    35UIKit                               0x0000000105b0e610 UIApplicationMain + 171
    36Develop-InsertViewer                0x00000001055ae752 main + 114
    37libdyld.dylib                     0x00000001095a192d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException</code><br>如果我在其他类(例如 UIToolBar)上执行 [自我外观],也会发生这种情况<br><br>任何的想法??</p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p>外观系统将所有属性限制在单个实现中 <code>TaggingAppearanceObjectSetterIMP</code> .该实现检查选择器的名称(使用 <code>_UIAppearanceTagObjectForSelector</code> )并在关联的对象缓存(存储在 <code>__UIAppearanceCustomizedSelectorsAssociationKey</code> 中)中查找。如果它不存在,它会调用 <code>_TagForSelectorWithAxes</code>找出映射到该选择器的内容,并更新缓存。<br><br>您使用自己的运行时诡计直接陷入了相当复杂的运行时诡计的中间。这爆炸了并不令人震惊......:D<br><br>基本问题至少是方法的名称必须是 <code>setBackgroundColor</code> ,不是 <code>swizzled_setBackgroundColor</code> .您可以通过混入实际的实现函数而不是方法来解决这个问题。你可以看看<a href="https://github.com/iosptl/ios7ptl/blob/master/ch24-DeepObjC/MethodSwizzle/NSNotificationCenter%2BRNSwizzle.m" rel="noreferrer noopener nofollow"> <code>NSNotificationCenter+RNSwizzle.m</code> </a>以手动执行此操作的示例。<br><br>如果在修复该问题后您仍然遇到其他微妙的问题,我不会感到惊讶。我的建议是(嗯,我的建议是“永远不要混合生产代码,它太脆弱了,”但如果你忽略了这个建议......)在 <a href="http://hopperapp.com" rel="noreferrer noopener nofollow">Hopper</a> 中拉出外观代码并跟踪实现,这样您就可以确保一切都对齐。这并不复杂,Hopper 的伪代码模式几乎可以向您展示发生了什么(我花了大约 2 分钟才弄清楚我在这里发布的内容)。也就是说,这是一个非常棘手的实现细节,它很容易在没有警告的情况下改变(导致新的崩溃)。如果您可以在不混淆的情况下做到这一点,我强烈建议您这样做。</p>
                                   
                                                <p style="font-size: 20px;">关于ios - Swizzling 符合 UI_APPEARANCE_SELECTOR 的属性,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/42677534/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/42677534/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - Swizzling 符合 UI_APPEARANCE_SELECTOR 的属性