我有一个UIViewController被推到一个容器控制器然后弹出,并使用分配工具,我可以看到视图控制器后来被销毁。但是,从未达到控制器dealloc中的断点。有谁知道为什么没有调用dealloc? ARC是否可以在不调用dealloc的情况下销毁对象?
另外,我已经禁用了NSZombies(有些人说可以导致dealloc不能开火)。
修改
Dealloc做的不多,只是打印到控制台,它永远不会被调用:
- (void)dealloc
{
NSLog(@"Deallocating...");
}
我无法发布容器控制器 - 它是专有的,太复杂了。 Dealloc在某些控制器上持续调用,而不是其他控制器。如果我能找到时间,我会尝试发布一个简化版本来重现问题。
有没有办法验证NSZombies是否被禁用?
EDIT2
我发布了乐器的截图;它看起来像是正确的解除分配。
答案 0 :(得分:92)
我刚遇到类似的问题。你有什么街区你指的是'自我'吗?我在我的init中有一些用于通知观察的块,我指的是'self'。在ARC下,self保留在块中。我的dealloc没有被调用,这就是我删除观察的地方。
诀窍是创建一个__weak(iOS 5+)或__unsafe_unretained(iOS 4.x)引用你的'self'并使用它来访问self或任何_iVars(这些将导致'self'被保留)在街区。这是一个例子。
__unsafe_unretained TableViewController *weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextObjectsDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
if (weakSelf.tableView) {
[weakSelf.tableView reloadData];
}
}];
答案 1 :(得分:22)
就我而言,它是NSTimer
。它保留了目标,因此当您完成视图控制器时,您需要使计时器无效。
答案 2 :(得分:20)
如果VC没有调用dealloc,那么我打赌你的代码中某处有一个循环引用,这会阻止ARC调用dealloc。
要检查的一些事项:
当我的委托声明没有使用__unsafe_unretained时,我被咬了屁股。
答案 3 :(得分:16)
即使使用ARC,您也可以手动检查参考计数:
CFIndex rc = CFGetRetainCount((__bridge CFTypeRef)myObj);
您可以确定您的代码是否在内存周期中挂起。
答案 4 :(得分:15)
我的问题是代表们。
检查你的代表!委托属性应指定weak
:
weak var delegate: SomeProtocol?
或
@property (weak, nonatomic) id<SomeProtocol> delegate;
答案 5 :(得分:10)
这是另一个提示(发生在我身上):
tl; dr:查看您的类实例变量,而不仅仅是类属性。您是否在代码中分配任何实例变量,而不是稍后将其设置为nil
?
我的头文件中有一堆属性(@property (nonatomic, strong)
和@property (nonatomic, weak)
)。我逐一评论这些属性,看看这是否会改变任何东西。它没。主要班级仍未被解除分配。所以问题不在于属性。
之后我做的是查看实例变量。我有一个实例变量(UIViewController
),我在viewDidLoad
创建了它。这个永远不会被解除分配!
当我删除这个变量时,我的主类叫做dealloc。
因为这个没有被释放,我的主要课程也没有被解除批评。将该实例变量作为属性移动解决了我的问题。
问题:我不知道为什么会这样。与实例变量相比,操作系统是否可以更好地控制类的属性?包含实例变量的父类由于其实例变量而未被释放似乎有点奇怪。
答案 6 :(得分:5)
你有NSZombieEnabled吗?看到这个问题:
Why is object not dealloc'ed when using ARC + NSZombieEnabled
我被这一段时间困扰了......