performSelector内存泄漏问题

2018-12-17  本文已影响17人  tom555cat

编译器并不会判断performSelector调用了什么方法,ARC不会添加释放方法(关键是也不知道采用何种释放手段)。

例如下面代码:

[NSObject alloc];

编译器在执行时,会添加objc_release方法来释放创建的NSObject对象,

->  0x10ea80666 <+54>: mov    rax, qword ptr [rip + 0x26bb] ; (void *)0x000000010fa2dea8: NSObject
0x10ea8066d <+61>: mov    rsi, qword ptr [rip + 0x269c] ; "alloc"
0x10ea80674 <+68>: mov    rdi, rax
0x10ea80677 <+71>: call   0x10ea80a18               ; symbol stub for: objc_msgSend
0x10ea8067c <+76>: mov    rdi, rax
0x10ea8067f <+79>: call   0x10ea80a24               ; symbol stub for: objc_release

而采用performSelector执行时,

[NSObject performSelector:@selector(alloc)];

编译结果如下,可以看到在函数返回之前,编译器也没有加入任何释放NSObject对象的代码。而我们知道通过alloc创建的对象,需要通过objc_release来释放,所以会造成内存泄漏。

0x10f918666 <+54>: mov    rax, qword ptr [rip + 0x26c3] ; (void *)0x00000001108c5ea8: NSObject
0x10f91866d <+61>: mov    rdx, qword ptr [rip + 0x269c] ; "alloc"
0x10f918674 <+68>: mov    rsi, qword ptr [rip + 0x269d] ; "performSelector:"
0x10f91867b <+75>: mov    rdi, rax
0x10f91867e <+78>: call   0x10f918a18               ; symbol stub for: objc_msgSend
->  0x10f918683 <+83>: mov    qword ptr [rbp - 0x28], rax
0x10f918687 <+87>: add    rsp, 0x30
0x10f91868b <+91>: pop    rbp
0x10f91868c <+92>: ret    

在这种情况下,继续执行,然后打开memory graph查看内存:


内存泄漏查看

果然发现了内存泄漏。

上一篇 下一篇

猜你喜欢

热点阅读