gpt4 book ai didi

objective-c - 状态应用程序 : sometimes panels are missing, 多线程可能存在问题

转载 作者:行者123 更新时间:2023-12-03 17:55:35 25 4
gpt4 key购买 nike

我有一个状态应用程序,发布全部内容很长,因此我将对其进行描述并仅发布部分代码:

  • 在xib文件中有两个对象:AboutController和PreferencesController;
  • 应用程序委托(delegate)能够启动 AboutController 和 PreferencesController 的面板;
  • 面板也在 xib 文件中;
  • 用户通过选择状态菜单项可以启动这两个面板;
  • 有一个计时器不断下载 HTML 页面并读取它;
  • 下载页面时,标签的 stringValue 会更改。但 stringValue 也可能从 PreferencesController 更改。页面是从后台线程下载的,但它是通过主队列更改的。

现在我有一些问题:

  • 当应用程序开始休眠(计算机进入待机状态)时,我是否必须使计时器无效,并在其返回时创建另一个计时器?
  • 标签在主队列中更新,所以我仍然需要使用互斥锁来保护标签访问?
  • 有时面板会丢失:在应用程序启动时,我可以通过单击菜单项来启动面板,但有时它们不会启动。我不知道如何总是重现此错误,它只是随机发生当应用程序通常处于事件状态 2/3 小时时,我必须重新启动应用程序才能解决此问题。

代码太长,只有一段代码:

- (void) checkPosts: (id ) sender
{
NSOperationQueue* queue=[NSOperationQueue new];
queue.maxConcurrentOperationCount=1;
[queue addOperationWithBlock:^
{
NSNumber* newPosts= [self updatePosts];
NSNumber* posts= [controller posts];
if([posts integerValue]!=[newPosts integerValue])
{
NSOperationQueue* queue=[NSOperationQueue mainQueue];
posts= newPosts;
[queue addOperationWithBlock:^
{
// This is where I may have a race condition
item.attributedTitle=[[NSAttributedString alloc]initWithString: [formatter stringFromNumber: posts] attributes: @{NSForegroundColorAttributeName : [controller color], NSFontAttributeName : [NSFont userFontOfSize: 12.5]}];
}];
// That's not so relevant:
NSUserNotification* notification=[NSUserNotification new];
notification.title= [NSString stringWithFormat: @"posts Changed to %@",posts];
notification.deliveryDate=[NSDate date];
notification.soundName= NSUserNotificationDefaultSoundName;
NSUserNotificationCenter* center=[NSUserNotificationCenter defaultUserNotificationCenter];
[center deliverNotification: notification];
center.delegate= self;
[controller setPosts: posts];
}
}];
}

一些背景信息:

  • 此方法在后台线程中工作;
  • [self updatePosts]下载HTML页面并返回帖子数量;
  • [controller posts] 使用 NSUserDefaults 读取之前的帖子数;
  • item 是状态菜单的菜单项。

更多详情

这就是我获取计时器的方式:

// In the applicationDidFinishLaunching method
timer=[NSTimer scheduledTimerWithTimeInterval: [interval integerValue ] target: self selector: @selector(checkReputation:) userInfo: nil repeats: YES];

计时器是一个属性:

@property (nonatomic, strong) NSTimer* timer;

interval是一个NSNumber,确保它的整数值大于或等于1。

最佳答案

尚不完全清楚这里发生了什么。您提供了大量信息,但并未提供给出明确答案所需的全部信息。我会先尝试解决您的问题:

Do I have to invalidate the timer when the application starts sleeping (computer goes in standby),and create another one when it returns on?

必须吗?不。应该为了国家的清洁和确定性吗?应该是。您可能应该准确指定如何设置计时器,因为您可能会遇到它与运行循环交互的问题......但我认为这不是您的问题。

The label is updated in the main queue, so I still have to protect the label access with a mutex?

只要从主线程/队列更新 UI,就应该没问题。这是带有 block 的标准设计方法。

Sometimes the panels are missing: at the start of the application I am able to launch panels by clicking a menu item, but sometimes they are not launching.I don't know how to reproduce this bug always, it just happens randomly when the application is active for 2/3 hours usually, I have to relaunch the application to go around this.

如果您不知道如何重现它,我不确定我们能否在“查看地点”之外为您提供帮助。我的第一个想法是,当应用程序激活时,您可能会重新创建主 Controller 的多个副本(因为您之前询问过这个问题,所以我假设您已经尝试用它做一些事情)。确保重复使用相同的 Controller 。

现在看代码。

NSOperationQueue* queue=[NSOperationQueue new];

queue 变量是方法范围内的本地变量。我没有看到保留/释放,所以我假设您正在使用 ARC。在这种情况下,您不会保留正在创建的新队列,并且一旦方法完成并且您离开了其作用域,只要您需要它,就不能保证其生命周期能够生存。您应该将 queue 设置为实例变量,以便它保留下来。这样,每次触发该方法时,队列都可以重用,并且它将保留足够长的时间供其他队列/线程使用。

我认为这可能是你最大的罪魁祸首。调整它并更新您的问题以反射(reflect)它如何影响您的应用的状况。

关于objective-c - 状态应用程序 : sometimes panels are missing, 多线程可能存在问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13992184/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com