0

我正在慢慢开发我的第一个简单的计时器应用程序,它开始慢慢变得生动起来。目前,当我的应用程序进入后台时,我没有保存数据,目前在编写我的应用程序时,它总是在我的测试期间保持加载状态,即使它在后台运行了一小段时间。所有这些都是在模拟器上完成的。

我的问题是我有一个带有 NSInteger 索引属性的表视图控制器

   @property NSInteger index;

我用来通过调用 doWork 方法逐步管理 NSArray 上的缓慢迭代。

我的 TVC 的初始设置和此属性是在视图准备好从另一个视图转移时执行的。每当我的应用程序收到本地通知或观察 UIApplicationWillEnterForegroundNotifications 时,都会在此属性和其他属性上完成更多工作。

这个属性的所有访问我都添加了调试日志,我只是对我所看到的感到困惑

  • PrepareForSegue
    • @ 19:38:29:058 - 调用方法 doWork 将我的属性从 -1 增加到 0,并设置本地通知。日志显示 self=0x10bb661f0
  • 我按下主页按钮将我的应用程序置于后台约 10 秒
  • 本地通知触发,我点击横幅使我的应用程序重新回到焦点
  • 我的 TVC 的 awakeFromNib 函数设置通知观察者如下

    NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
    [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification 
                                                      object:nil
                                                       queue:mainQueue
                                                  usingBlock:^(NSNotification *note) {
                                                   [self doWork];
                                            }];
    
  • 此通知会触发两次!(出于某种原因?)每次导致我的 doWork 方法被调用

    • @ 19:38:45:832 - doWork 立即显示我的属性现在回到 -1 而不是在被设置为背景之前设置为 0,它再次递增到 0。它还显示 self 在 self=0x10974bbd0 时不同,a当应用程序处于前台时,它仍然保留在当前值。
    • @ 19:38:45:836 - doWork 从第二次通知调用中再次调用,我的属性现在正确地从最后一次调用中仍然为 0,它再次增加到 1。
  • 之后,我的应用程序委托还调用了 didReceiveLocalNotification 方法,该方法最终还将通过通知中心观察者设置中的另一个块调用相同的 doWork 方法,与上面详述的设置相同。
    • @ 19:38:45:857 - doWork 被调用,并且该属性再次从设置的 1 变回 0...并再次递增回 1。

我只是不明白发生了什么。我的 TVC 中的大多数属性可能仍然很好,因为我显示 TVC 内容的其余逻辑继续正常工作。为什么我的 NSInteger 变得如此混乱?

我想也许线程和本地通知处理可能同时发生一些问题,我希望添加 mainQueue 会对此有所帮助,我之前已将此设置为 nil。可悲的是它没有任何区别。

我想知道为什么只有很短的时间后,自我就会改变。我天真地假设一切似乎都在回到前台(视图仍然显示,除了这个 NSInteger 属性之外,它的所有数据似乎都完好无损),self ptr 和 object 将是相同的。可以想象它可能以某种方式被操作系统重新定位,但这不应该导致属性发生变化。

我正在使用可可伐木工进行日志记录,并且我已关闭 ASYNC 日志记录,如下所示

    #define LOG_ASYNC_ENABLED NO 

这至少应该意味着日志调用会阻塞,直到他们登录为止。我可以理解,如果我确实有一些线程问题,那么日志记录顺序可能会有点疑问。但是对于应用程序进入后台后上述属性的初始损坏,从我将 0 写入该属性,然后再从其中读取 -1 大约 10 秒。在这一点上,这显然不是线程时间问题。

为什么会两次通知我进入前台?如果我的属性留在我设置它们的地方,那并不重要,但仍然让我觉得有点奇怪。

我在这个块中使用 self 是否有问题,我已经看到有时您可能希望对这些块使用弱 self 指针,但我也看到了直接使用 self 的示例。

任何有关理解和希望解决此问题的帮助将不胜感激。我有点卡住了,看不出我做错了什么!

干杯

4

1 回答 1

0

因此,Woofbeans 和 Phillip Mills 发现我的问题的答案是,每次我进入这个 TVC 时都会调用我的 awakeFromNib,而且我没有在这些通知上删除观察者,导致过时的未显示的 TVC 无限期地存在。我没有意识到我重现问题的关键部分。

进入 TVC,出来,再进去,然后你会在应用程序中看到重复的警报,这是由于原始 TVC 仍然存在这一事实引起的,被我自己的块中对自我的强烈引用所保留。

我将把这个 doWork 功能重构到我的模型中,以便它可以持续存在并更好地处理,而与恰好显示的任何视图无关。

我还更改了我的块代码以在块中使用弱自指针,希望阻止该块纯粹因为留下块而导致任何对象持续存在。

大家加油!

于 2014-04-11T09:35:06.567 回答