Iphone 有没有一种方法可以;“发现神秘”是什么意思。。。?

Iphone 有没有一种方法可以;“发现神秘”是什么意思。。。?,iphone,memory-management,xcode4,retain,Iphone,Memory Management,Xcode4,Retain,最近我正在修复某人的代码。有一个很大的班级是不会被解雇的。你必须用5到6个版本才能把它释放出来 我仔细查看了大班,最终找到了需要发布的各种内容 这让我想到:必须有一种非常简单的方法来“找到”一个对象上的所有保留。。我说得对吗 那么,有没有一种简单的方法来“查找对象上的所有保留”?XCode或仪器中是否有其他人都知道的按钮 当你找不到这样的秘密时,你会怎么做 因此,在iOS世界中,如果有人知道“显示此对象上所有保留内容的来源”按钮——谢谢 p.S.注意,没有泄漏,这个问题与泄漏完全无关。物体只是“

最近我正在修复某人的代码。有一个很大的班级是不会被解雇的。你必须用5到6个版本才能把它释放出来

我仔细查看了大班,最终找到了需要发布的各种内容

这让我想到:必须有一种非常简单的方法来“找到”一个对象上的所有保留。。我说得对吗

那么,有没有一种简单的方法来“查找对象上的所有保留”
?XCode或仪器中是否有其他人都知道的按钮

当你找不到这样的秘密时,你会怎么做

因此,在iOS世界中,如果有人知道“显示此对象上所有保留内容的来源”按钮——谢谢

p.S.注意,没有泄漏,这个问题与泄漏完全无关。物体只是“完全正确”不会释放


以后

Fabio提供的真正令人震惊的解决方案: 法比奥为这个问题提供了一个惊人的解决方案。用九个字来说,就是:

-(id)retain
    {
    NSLog(@"%@", [NSThread callStackSymbols]);
    return ([super retain]);
    }
这在许多情况下都非常有用,并导致了许多其他有用的事情。法比奥,你可能永远为我省下了每年两周的工作。谢谢


顺便说一句,如果您刚刚开始了解这一点并努力处理输出,我看到通常会有许多块具有“UINib instantiateWithOwner:”。看起来这些将首先出现,重要的块将随后出现。

只是猜测。。。但是您可以覆盖调用super的自定义类的retain方法,并抛出一个漂亮的NSLog来打印调用堆栈


使用来自Joe的实际代码进行更新 另一个重要细节是[NSThread callStackSymbols]返回NSString的NSArray,这些NSString可以被过滤并用于其他目的。例如,在复杂的动态代码中,检查一个方法是否正确地引发另一个方法

注:
在ARC环境中,您需要首先将
-fno objc ARC
添加到编译器标志中,以允许您覆盖retain并调用super。

您尝试过在Xcode中使用“Build&analysis”吗


它非常有助于了解未被释放的对象的底部。

仪器及其内存管理工具是您的朋友。漏洞和僵尸是两个最有价值的工具。使用它们

Product->Profile(或Cmd-I)

在自定义类“retain”上放置断点 可以在retain上设置符号断点,然后将其设置为自定义类的retain方法。这里的问题是retain是
NSObject
上的一个方法,因此在放置断点时可以选择所有objective-c类

在这种情况下,最好通过调用super覆盖自定义类的retain方法,这样它就不会做任何事情,但您可以在其中放置一个断点

使用断点操作记录调用方 要添加断点操作,请双击蓝色标记。在列表中找到断点并按下右侧的+按钮。然后选择调试器命令并在该字段中添加GDB命令第1帧,这将显示retain的调用者。通过这一点,您可以了解所有保留的内容及其来源。当以类似的方式记录发布时,您可以检查额外的发布是什么


这仍然有点乏味,但这是我能想到的最好的方法。

不幸的是,通过编程确定对象的“所有者”并不容易,因为“对象所有权”的概念是一种编码约定(除非启用垃圾收集)

堆栈日志记录通常很有用(我通常在
bt;continue
中使用一些断点),但这只会告诉您调用retain的函数,而不是“更大的图景”(例如,您可以使用
[ivar2 release];ivar2=ivar1;ivar1=nil;
来“转移所有权”)。有时它是一个UIKit泄漏,所以你没有源代码,你真的必须去挖掘


但是,如果不是泄漏,请多次调用
-release
,查看它在哪里崩溃

Instruments可以向您显示应用程序中任何Obj-C对象的每个malloc、release和retain的调用堆栈,无需更改代码。当您使用ARC时,它会起作用,而fabio的解决方案并非如此

它对于发现那些神秘的保留物非常有用——例如,当一个对象在应该释放的时候无法释放

以下是方法:

  • CMD+I(产品/简介)
  • 当仪器弹出时,选择“分配”(而不是泄漏)
  • 你的应用程序应该运行
  • 做任何让你的神秘发生的事
  • 选择左侧面板上的“分配”仪表
  • 按CMD+1或选择右侧带有波浪的圆圈。在右下角的面板中,勾选“记录引用计数”选项。这很重要,否则将只记录mallocs和frees
  • 在列表右上角的搜索框中,键入类的名称(例如BCMyObject)
  • 这将过滤“统计信息”列表,以显示当前有多少类实例处于活动状态。#Persistent列显示有多少实例处于活动状态
  • 单击该行,然后单击类名旁边的小箭头->。您将看到面包屑显示“统计信息>分配摘要>BCMyobject”
  • 这将显示所述类的所有实例(以及哪些实例是活动的)
  • 选择一个实例,然后再次单击箭头(这次按地址)
  • 现在,您将在面包屑中看到“统计信息>分配摘要>BCMyObject>历史记录:0xADDRESS”
  • 每次对象被malloc保留或释放时,都会列出此列表
  • 现在,在“记录引用计数”选项所在的左侧面板中,按类似于带连接框的条的图标,或按CMD+3。
    -(id) retain {
    NSLog(@"%@", [NSThread callStackSymbols]);
    return ([super retain]);
    }