我有一个状态应用程序,发布它很长,所以我将对其进行描述并仅发布部分代码:
- 在 xib 文件中有两个对象:AboutController 和 PreferencesController;
- 应用程序委托能够启动 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 页面并返回帖子数量;
- [控制器帖子] 使用 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。