我想在@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上失败了。
组件与测试方法不同:
- (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
答案 0 :(得分:4)
UIPasteboard
在iOS 10中成为class cluster。最简单的方法是停止应用中的断点并在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];
// ....
}
当然,这不是为类集群实现调配的安全方法 - 不能保证在运行时不会遇到任何其他私有UIPasteboard
子类。