【问题标题】:Draw the contents of an array modified in the background绘制在后台修改的数组的内容
【发布时间】:2015-05-11 14:49:35
【问题描述】:

我有一个后台线程,它运行并修改对象内NSMutableArray 的内容。这需要很长时间(几个小时)才能运行,并且我希望定期在 drawRectNSView 中绘制数组的内容,以检查进度并查看中间结果。

我的对象有一个协议,其方法名为:didChange:

// How I start my background thread
[self performSelectorInBackground:@selector(startProcessing) withObject:nil];

- (void)startProcessing {
    myObject.delegate = self;
    [myObject start];
}

// My protocol implementation
- (void)myObjectDidChange:(myObjectClass *)sender {
    [myView setNeedsDisplay:YES];
}

// My View's drawRect (pseudo code)
- (void)drawRect {
    [myObject drawInContext:context];
}

所有作品,除了支持所有这一切的NSMutableArray 在绘图发生时被更改。我该怎么做?在进行更新时,我是否会以某种方式暂停后台线程中的处理?

编辑:这是我正在绘制的那种显示(虽然要复杂得多):

任何帮助表示赞赏。

【问题讨论】:

  • 如果它是一个数组,那么使用 tableview 听起来是正确的选择。
  • 我正在绘制一个带有连接的节点矩阵。所以我需要画出它所代表的东西,而不仅仅是显示一个列表。
  • 我会添加一张图片,让您了解我在画什么。
  • 阵列有多大?当被要求避免突变问题时,您能否返回不可变副本?
  • 您是否尝试过制作数组atomic?这样,您将在另一个线程更改其中的某些内容之前或之后获得该数组,但这绝对是一个可行的对象...... @bbum 对此有一个很好的解释:stackoverflow.com/a/589392/2242359

标签: objective-c background-process osx-yosemite drawrect


【解决方案1】:

如果你在后台线程中做某事并且你想更新 UI,它通常在主线程上完成,所以在你的对象确实发生变化时你会这样做,可能是这样的:

// My protocol implementation
- (void)myObjectDidChange:(myObjectClass *)sender {
     dispatch_async(dispatch_get_main_queue(), ^{
      [self drawRect];  //Or any drawing function you are trying to do
  }); 
}

【讨论】:

  • 这没有回答问题。
【解决方案2】:

我已经使用NSLock 来锁定startdrawInContext 方法的外循环。我仍然不确定这是否是最好的方法,并且几天内不会接受这个答案,以防有更好的答案。

- (void)start {
   for(int i=0; i < MAX; i++) {
      [self.updateLock lock];
      ....
      [self.updateLock unlock];
   }
}

- (void)drawInContext:(CGContextRef)context {
   [self.updateLock lock];
   ...
   [self.updateLock unlock];
}

【讨论】:

  • 您似乎没有使用条件锁的“条件”部分。所以,你可以使用NSLock。还有其他同步原语,如@synchronized 或串行调度队列。对于这个特定的用例,@synchronized 可能是最简单、最不容易出错且最有效的。
  • 感谢 Ken,用 NSLock 替换并编辑了答案。
猜你喜欢
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多