美文网首页
performSelector内存泄漏问题

performSelector内存泄漏问题

作者: tom555cat | 来源:发表于2018-12-17 18:38 被阅读17次

    编译器并不会判断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查看内存:


    内存泄漏查看

    果然发现了内存泄漏。

    相关文章

      网友评论

          本文标题:performSelector内存泄漏问题

          本文链接:https://www.haomeiwen.com/subject/jzickqtx.html