我正在使用self.bound
来获取drawRect
方法中的UIView大小。但是现在,使用XCode 9,我收到了这个警告:
主线程检查器:在后台线程上调用UI API: - [UIView bounds]
在drawRect
方法中获取视图大小的正确方法是什么?
像这样:
override func drawRect(rect: CGRect)
let bds = DispatchQueue.main.sync {
return self.bounds
}
// ....
}
但是drawRect
首先在后台线程上被调用的事实是一个坏迹象 - 除非你使用CATiledLayer或其他一些内置架构来做到这一点。你应该首先担心这一点。
我终于找到了问题的解决方案。我现在重写UIView的layoutSubviews
以保持类成员中的视图边界:
- (void)layoutSubviews
{
[super layoutSubviews];
m_SelfBounds = self.bounds;
}
在那之后,我只是在m_SelfBounds
方法中使用drawRect
。
使用Grand Central Dispatch的“屏障”功能允许并发读取操作,同时在写入期间阻止这些操作:
class MyTileView: UIView
{
var drawBounds = CGRect(x: 0, y: 0, width: 0, height: 0)
let drawBarrierQueue = DispatchQueue(label: "com.example.app",
qos: .userInteractive, // draw operations require the highest priority threading available
attributes: .concurrent,
target: nil)
override func layoutSubviews() {
drawBarrierQueue.sync(flags: .barrier) { // a barrier operation waits for active operations to finish before starting, and prevents other operations from starting until this one has finished
super.layoutSubviews();
self.drawBounds = self.bounds
// do other stuff that should hold up drawing
}
}
override func draw(_ layer: CALayer, in ctx: CGContext)
{
drawBarrierQueue.sync {
// do all of your drawing
ctx.setFillColor(red: 1.0, green: 0, blue: 0, alpha: 1.0)
ctx.fill(drawBounds)
}
}
}