Reputation: 149
I am using self.bound
to get the UIView size in drawRect
method. But now, with XCode 9, I get this warning:
Main Thread Checker: UI API called on a background thread: -[UIView bounds]
What is the right way to get the view size in drawRect
method?
Upvotes: 3
Views: 794
Reputation: 33359
Use the "barrier" feature of Grand Central Dispatch to allow concurrent read operations while blocking those operations during a write:
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)
}
}
}
Upvotes: 0
Reputation: 535231
Like this:
override func drawRect(rect: CGRect)
let bds = DispatchQueue.main.sync {
return self.bounds
}
// ....
}
But the fact that drawRect
is being called on a background thread in the first place is a bad sign — unless you're using CATiledLayer or some other built-in architecture that does this. You should be worrying first and foremost about that.
Upvotes: 7
Reputation: 149
I finally found a solution for the problem. I am now overriding layoutSubviews
of UIView to keep the view bounds in a class member:
- (void)layoutSubviews
{
[super layoutSubviews];
m_SelfBounds = self.bounds;
}
After that, I am just using m_SelfBounds
in drawRect
method.
Upvotes: 5