- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我会尽量简短明了:我有一个对象,它的 dealloc 方法正在被调用。我还有一个 NSTimer 每 3 秒被调用一次以记录以控制所述对象的当前保留计数。
需要说明的是:我知道 NSTimer 会保留该对象。即使考虑到这一点,情况仍然不成立。
无论如何 - 在这个计时器触发时,对象的保留计数被记录为 3。这让我感到困惑有两个原因:
非常感谢任何帮助。谢谢。
编辑:代码:
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(logRetainCount) userInfo:nil repeats:YES];
^ 在 viewDidLoad 中设置
- (void)logRetainCount
{
NSLog(@"own retain count: %ld", CFGetRetainCount((__bridge CFTypeRef)self));
}
^ 日志保留计数的方法
- (void)dealloc {
NSLog(@"view controller deallocated");
}
^ VC 中实现的应该被释放的 dealloc 方法
控制台输出:
own retain count: 5
view controller deallocated
own retain count: 3
最佳答案
你问:
Is it possible for
dealloc
to be called on an object whose retain count is NOT zero?
由于您使用的是 ARC,我们不再在该上下文中使用“保留计数”。但是在回答你的问题时,不,在有强引用的情况下不能释放对象。当你调用 scheduledTimerWithTimeInterval
,如果这是一个重复计时器,它将保持对 target
的强引用。 ,防止目标被释放(至少在调用计时器的 invalidate
之前)。
考虑:
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(logRetainCount) userInfo:nil repeats:YES];
}
- (void)logRetainCount {
NSLog(@"own retain count: %ld", CFGetRetainCount((__bridge CFTypeRef)self));
}
- (void)dealloc {
NSLog(@"view controller deallocated");
}
@end
当我推送到这个 View Controller 时,我在控制台上看到以下内容:
2016-09-15 15:50:10.279 MyApp[7777:159811] own retain count: 32016-09-15 15:50:13.340 MyApp[7777:159811] own retain count: 3
And when I pop that view controller off, I see:
2016-09-15 15:50:16.338 MyApp[7777:159811] own retain count: 22016-09-15 15:50:19.270 MyApp[7777:159811] own retain count: 2
Note, we do not see "view controller deallocated" appear in the console.
When I click on Xcode 8's "Debug Memory Graph" button, we can see that the timer is still keeping a strong reference to it:
You ask:
- Why is
dealloc
being called if the object's retain count is not ever reaching 0?
It can't be. So, we must have multiple instances of the view controller involved here, one that has the repeating timer that isn't deallocated, and one without the timer, that is deallocated when its last strong reference is resolved. But whatever object is the target
of the timer will still have a strong reference to it until the timer is invalidated, and it will not be deallocated until the timer has its invalidate
called.
- Since
dealloc
is getting called, shouldn't, at the very least, the retain count be 1 since theNSTimer
instance is holding onto it?
No, while the repeating timer is firing, its target cannot be deallocated. We must be talking about multiple instances of the view controller (or, unlike the example above, the target
of the timer wasn't the view controller).
There are lots of ways to accidentally introduce additional instances of a view controller. For a random example (one that I've seen here on Stack Overflow more than once), consider that you did a segue between two view controllers, and had a prepareForSegue
that did something like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
SecondViewController *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
secondViewController.property = @"foo";
}
这是不正确的,因为除了 segue 实例化的 View Controller (segue.destinationViewController
)之外,上面的 prepareForSegue
将创建另一个实例。在 prepareForSegue
中创建的那个一旦它超出范围就会被释放,但是由 segue 创建的那个不会被释放,因为在 viewDidLoad
中创建了重复计时器。 .
我并不是说这就是你所做的,但它说明了一种可能的方式来获得你所描述的行为。
但是,简而言之,不,在 ARC 中,一个仍然有任何强引用的对象将不会被释放。只有当最后一个剩余的强引用被移除时,它才会被释放。您问题中的代码不能单独产生您描述的行为。您必须处理一些额外的 View Controller 实例或类似的好奇。我可能会建议你创建一个 simple example重现了您描述的问题,因为您问题中的代码没有。还有其他事情正在发生。
关于ios - 是否可以在保留计数不为零的对象上调用 dealloc?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39520663/
演讲的主题是 Objective-c 中的类和对象。我无法理解 [super dealloc] 的概念。我们有一些类 myClass,它继承自 NSObject。它有一些方法并从父类继承其他方法。所以
对于 ARC,有时我仍然需要编写一个 -dealloc 方法来进行一些清理。在极少数情况下,我需要引用实例的属性才能正确进行清理。例如从 NSNotificationCenter 中注销给定的发送者对
如果我有一个由 View Controller 控制的 View 堆栈,并且当我从 View 堆栈中弹出 View 时调用了 View 的 dealloc(包含 [super dealloc] )方法
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 9 年前。 Improve
当我的应用程序开始在我的自定义注释方法中崩溃时,我了解到我的内存有问题。我确信管理 map 的 viewcontroller 100% 应该已经从 View 堆栈中弹出。 这里是注释的代码,TaxiA
我刚刚一直在阅读有关如何正确地在 init 方法中失败的信息,并且文档似乎彼此不同意。一个建议抛出异常,而其他建议清理并返回 nil。当前的最佳做法是什么? 最佳答案 我相信普遍接受的做法是在失败时返
这是我的情况。这很复杂,所以请耐心等待。 我有一个 View 类,我们称它为 MyView。它创建一个加载指示器 subview ,然后启动将加载数据的后台操作。它还创建了一个 block ,后台队列
我正在设置 AMScrollingNavbar在 swift 。当我尝试转换时 - (void)dealloc { [self stopFollowingScrollView]; } 到 func
我正在尝试执行以下操作: 获得类'dealloc IMP 向所述类中注入(inject)一个自定义 IMP,它基本上调用原始的 dealloc IMP 当所述类的一个实例被释放时,两个 IMP 都应该
在我的一个 View Controller 中,它将自身添加为 UITextViewTextDidEndEditingNotification 通知的观察者,如下所示 [[NSNotification
我正在初始化一个对象,然后内联配置它。但是,不是在配置前一个实例(如果之前已分配)之前将其释放(在紧随其后的行中),而是推迟释放。因此,我对它所做的所有配置最终都成为一个已释放的对象 - 这当然不是我
是否需要将所有声明为IBOutlet的带有retain修饰符的@property设置为nil - (void)dealloc 方法?如果我不这样做,内存会被消耗/浪费吗? 假设自动引用计数关闭。 最佳
这是我在应用程序中切换 View 的方式: CGRect frame = self.view.frame; frame.origin.x = CGRectGetMaxX(frame);
假设有一个带有两个选项卡 A 和 B 的选项卡栏 Controller ,其中 A 是导航 Controller 。 当用户在A中时,他可以推送A1,然后推送A2,它们都是 View Controll
我有一个加载两个 View Controller 的 Root View 。例如:FirstVC、SecondVC。 当应用程序启动时,我将 FirstVC 显示为 Root View Control
我有一个基于导航的应用程序,可以在一些 ViewController 之间切换。如果我按下“goHome”按钮,方法 popViewControllerAnimated: 被调用,然后我返回到主屏幕。
我正在尝试调试为什么我的 dealloc 覆盖没有在我的一个 View Controller 上被调用。 我有一个通过 Storyboard设置的 View Controller 。我已经重写了所有
对于我的 iOS 7 应用,只想确认: dealloc 是否仍会被调用? 与是否开启ARC有关系吗? 最佳答案 是的,无论您是否使用 ARC,dealloc 都会在对象被释放时调用。 但是请注意,当您
我很难适应 C++ 处理动态和自动内存的方式。 我的问题: 指向自动分配实例的指针是否可以保留该实例解除分配,即使实例化范围已离开? 在this帖子我读到所有指向 dealloc 内存的指针都是无效的
我有三个 UIViewControllers,每当我关闭它们时,它们的所有 dealloc 方法都会被调用。这正是我想要发生的事情,这样内存就不会膨胀。 但是,当我运行配置文件来测试内存使用情况和一些
我是一名优秀的程序员,十分优秀!