3

我想调配@property string方法UIPasteboard

+ (void) load {
    ....
    [UIPasteboard jr_swizzleMethod:@selector(string) withMethod:@selector(stringSwizzle) error:nil];
    [UIPasteboard jr_swizzleMethod:@selector(setString:) withMethod:@selector(setStringSwizzle:) error:nil];
    ....
}

当我调用[[UIPasteboard generalPasteboard] setString:@"test"];它时,输入我的调酒方法。它适用于 iOS 7、iOS 8 和 iOS 9。但是,它在 iOS 10 上失败。

组装不同的测试方法:</p>

- (void) pasteboradTest {
    [aUIPasteboard setString:@"test"];
}

在 iOS 9 上:

    0xced0a <+0>:  push   {r7, lr}
    0xced0c <+2>:  mov    r7, sp
    0xced0e <+4>:  sub    sp, #0x8
    0xced10 <+6>:  movw   r2, #0xa51c
    0xced14 <+10>: movt   r2, #0x0
    0xced18 <+14>: add    r2, pc
    0xced1a <+16>: movw   r3, #0xa2e2
    0xced1e <+20>: movt   r3, #0x0
    0xced22 <+24>: add    r3, pc
    0xced24 <+26>: ldr    r3, [r3]
    0xced26 <+28>: movw   r9, #0xbc8e
    0xced2a <+32>: movt   r9, #0x0
    0xced2e <+36>: add    r9, pc
    0xced30 <+38>: movw   r12, #0xc298
    0xced34 <+42>: movt   r12, #0x0
    0xced38 <+46>: add    r12, pc
    0xced3a <+48>: str    r0, [sp, #0x4]
    0xced3c <+50>: str    r1, [sp]
    0xced3e <+52>: ldr.w  r0, [r12]
    0xced42 <+56>: ldr.w  r1, [r9]
    0xced46 <+60>: blx    r3
    0xced48 <+62>: add    sp, #0x8
    0xced4a <+64>: pop    {r7, pc}

在 iOS 10 上:

    0x10008f78c <+0>:  stp    x29, x30, [sp, #-16]!
    0x10008f790 <+4>:  mov    x29, sp
    0x10008f794 <+8>:  sub    sp, sp, #16               ; =16 
    0x10008f798 <+12>: adrp   x8, 9
    0x10008f79c <+16>: add    x8, x8, #592              ; =592 
    0x10008f7a0 <+20>: adrp   x9, 11
    0x10008f7a4 <+24>: add    x9, x9, #3480             ; =3480 
    0x10008f7a8 <+28>: adrp   x10, 12
    0x10008f7ac <+32>: add    x10, x10, #1776           ; =1776 
    0x10008f7b0 <+36>: str    x0, [sp, #8]
    0x10008f7b4 <+40>: str    x1, [sp]
    0x10008f7b8 <+44>: ldr    x10, [x10]
    0x10008f7bc <+48>: ldr    x1, [x9]
    0x10008f7c0 <+52>: mov    x0, x10
    0x10008f7c4 <+56>: mov    x2, x8
    0x10008f7c8 <+60>: bl     0x100094cb8               ; symbol stub for: objc_msgSend
    0x10008f7cc <+64>: mov    sp, x29
    0x10008f7d0 <+68>: ldp    x29, x30, [sp], #16
    0x10008f7d4 <+72>: ret
4

1 回答 1

4

UIPasteboard成为 iOS 10 中的类集群。注意这一点的最简单方法是在应用程序的断点处停止并在 lldb 中执行以下命令:

(lldb) po [UIPasteboard generalPasteboard]
<_UIConcretePasteboard: 0x6000000087a0>

这就是 swizzling 不起作用的原因——您更改了UIPasteboard类中的实现,但您的应用程序调用了_UIConcretePasteboard私有子类的实现。

您可以尝试使用以下代码解决此问题:

+ (void) load {
    // ....
    [[[UIPasteboard generalPasteboard] class] jr_swizzleMethod:@selector(string) withMethod:@selector(stringSwizzle) error:nil];
    [[[UIPasteboard generalPasteboard] class] jr_swizzleMethod:@selector(setString:) withMethod:@selector(setStringSwizzle:) error:nil];
    // ....
}

当然,这不是为类集群实现 swizzling 的安全方法 - 无法保证在运行时不会遇到任何其他私有UIPasteboard子类。

于 2016-11-24T19:27:54.280 回答