ios 未在 ARC 应用程序上调用 Dealloc
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9219030/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dealloc not being called on ARC app
提问by rob
I have a UIViewController that is pushed onto a container controller and then popped off, and using the allocations instrument, I can see that the view controller is destroyed afterwards. However, a breakpoint in the controller's dealloc is never reached. Does anyone know why dealloc isn't called? Is it possible for ARC to destroy an object without calling dealloc?
我有一个 UIViewController,它被推到一个容器控制器上,然后弹出,使用分配工具,我可以看到视图控制器随后被销毁。然而,控制器的dealloc 中的断点永远不会到达。有谁知道为什么不调用 dealloc ?ARC 是否可以在不调用 dealloc 的情况下销毁对象?
Also, I've disabled NSZombies (some have said that can cause dealloc not to fire).
另外,我已经禁用了 NSZombies(有人说这会导致 dealloc 不触发)。
Edit:
编辑:
Dealloc doesn't do much, just prints to the console, and it never gets called:
Dealloc 没有做太多事情,只是打印到控制台,并且永远不会被调用:
- (void)dealloc
{
NSLog(@"Deallocating...");
}
- (void)dealloc
{
NSLog(@"Deallocating...");
}
I can't post the container controller–it's proprietary and too complicated. Dealloc is called consistently on some controllers and not others. If I can find the time I will try and post a simplified version that reproduces the problem.
我不能发布容器控制器——它是专有的,而且太复杂了。Dealloc 在某些控制器上被一致调用,而在其他控制器上则不调用。如果我能找到时间,我会尝试发布一个重现问题的简化版本。
Is there any way to verify that NSZombies is disabled?
有什么方法可以验证 NSZombies 是否已禁用?
Edit2
编辑2
I'm posting a screenshot from instruments; it looks to me like it's properly deallocating.
我正在发布仪器的屏幕截图;在我看来,它正在正确解除分配。
回答by mikeq
I just ran across a similar issue. Do you have any blocks where you are referring to 'self'? I had some blocks for notification observation in my init where I was referring to 'self'. Under ARC self is retained in blocks. My dealloc wasn't getting called and that was where I was removing the observation.
我刚刚遇到了类似的问题。你有没有提到“自我”的块?我在我的 init 中有一些用于通知观察的块,我指的是“自我”。在 ARC 下,self 保留在块中。我的 dealloc 没有被调用,这就是我删除观察的地方。
The trick is to create a __weak (iOS 5+) or __unsafe_unretained (iOS 4.x) reference to your 'self' and use that to access self or any _iVars (these will cause 'self' to be retained as well) in the block. Here's an example.
诀窍是创建一个 __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];
}
}];
回答by Almas Sapargali
In my case it was NSTimer
. It retains its target so you need to invalidate timer when you're done with view controller.
就我而言,它是NSTimer
. 它保留其目标,因此您需要在完成视图控制器后使计时器无效。
回答by Dean Liu
If dealloc is not being called by the VC, then I would bet there is a circular reference somewhere in your code, which is preventing ARC from calling dealloc.
如果 VC 没有调用 dealloc,那么我敢打赌您的代码中某处存在循环引用,这会阻止 ARC 调用 dealloc。
Some things to check:
要检查的一些事项:
- Do you have an object instantiated that references back to the VC?
- If you need to reference the VC be sure you have used '__unsafe_unretained' attribute or 'weak' (iOS5+) so that the retain cycle does not occur.
- 你有一个实例化的对象引用回 VC 吗?
- 如果您需要引用 VC,请确保您使用了 '__unsafe_unretained' 属性或 'weak' (iOS5+) 以便不会发生保留循环。
I was nipped in the butt when my delegate declarations did not utilize __unsafe_unretained.
当我的委托声明没有使用 __unsafe_unretained 时,我被扼杀了。
回答by jbbenni
Even with ARC you can inspect the reference count manually:
即使使用 ARC,您也可以手动检查引用计数:
CFIndex rc = CFGetRetainCount((__bridge CFTypeRef)myObj);
You can know for sure if your code is hung in a memory cycle.
您可以确定您的代码是否挂在内存周期中。
回答by kgaidis
My problem was delegates.
我的问题是代表。
Check your delegates! The delegate property should have weak
specified:
检查您的代表!委托属性应该已weak
指定:
weak var delegate: SomeProtocol?
weak var delegate: SomeProtocol?
or
或者
@property (weak, nonatomic) id<SomeProtocol> delegate;
@property (weak, nonatomic) id<SomeProtocol> delegate;
回答by Andrei
Here's another tip (happened to me):
这是另一个提示(发生在我身上):
tl;dr:Look at your class instance variables as well, not just the class properties. Are you allocating any instance variable in code, and not setting it to nil
later?
tl;dr:还要查看您的类实例变量,而不仅仅是类属性。您是否在代码中分配任何实例变量,而不是nil
稍后将其设置?
I had a class with a bunch of properties (@property (nonatomic, strong)
and @property (nonatomic, weak)
) in its header file. I commented out those properties one by one to see whether this will change anything. It did not. The main class was still not being deallocated. So the problem was not in the properties.
我的头文件中有一个带有一堆属性(@property (nonatomic, strong)
和@property (nonatomic, weak)
)的类。我将这些属性一一注释掉,看看这是否会改变什么。它没。主类仍然没有被释放。所以问题不在属性上。
What I did afterwards was look at the instance variables. I had one instance variable (which was a UIViewController
), which I created on viewDidLoad
. This one nevergot dealloc-ed!
之后我所做的是查看实例变量。我有一个实例变量(它是 a UIViewController
),我在viewDidLoad
. 这个从未被解除分配!
When I removed this variable, sure enough, my main class called dealloc.
当我删除这个变量时,果然,我的主类调用了 dealloc。
So because this one wasn't dealloc-ed, my main class was not dealloc-ed either. Moving that instance variable as a property solved the problem for me.
所以因为这个没有被释放,我的主类也没有被释放。将该实例变量作为属性移动为我解决了这个问题。
Question:I'm not sure why this happens though. Does the operating system have better control over the properties of a class, than over the instance variables? It seems a bit weird that the parent class which contains the instance variable doesn't get released because of its instance variable.
问题:我不确定为什么会发生这种情况。操作系统对类的属性的控制是否比对实例变量的控制更好?包含实例变量的父类由于其实例变量而没有被释放,这似乎有点奇怪。
回答by TomSwift
Do you have NSZombieEnabled? See this question:
你有 NSZombieEnabled 吗?看到这个问题:
Why is object not dealloc'ed when using ARC + NSZombieEnabled
为什么在使用 ARC + NSZombieEnabled 时对象没有被释放
I was stumped by this for a while myself...
我自己也被这个难住了一段时间...