Reputation: 6585
Is it wrong to call async from Swift object initializer such as this one
let serialQueue = DispatchQueue(label: "com.myApp.SerialQueue")
private let property1:Int?
public override init()
{
super.init()
/* Initialize properties */
setupProperties()
serialQueue.async { [unowned self] in
self.nonBlockingSetup()
}
}
private func setupProperties() {
self.property1 = 1
}
private func nonBlockingSetup() {
//Some non-blocking code that shouldn't run on main thread
}
Some people say async call is problematic before init returns. Need to know what Swift language says about it.
EDIT: Is there any difference if I modify the code as follows:
public override init()
{
super.init()
/* Initialize properties */
setupProperties()
callNonBlockingCodeAsync()
}
private func callNonBlockingCodeAsync() {
serialQueue.async { [unowned self] in
self.nonBlockingSetup()
}
}
Upvotes: 0
Views: 1184
Reputation: 8502
In general, a constructor should not do any meaningful work.
Having a constructor that executes code delayed (because it's async) will be unexpected for anyone using that class (quite possibly including you in 6 months), and can therefore lead to bugs. In such cases it's usually better to have a separate initialization method, which makes it clear to an api user that there is something more going on.
If you absolutely want to make sure the initialization method is called, I usually make the constructor private and add a class method for construction. Again this signals api users that there is something going on behind the scenes.
Upvotes: 1
Reputation: 2869
To answer your question, I tried out the simple example.
Errors
are very much self explanatory, in the initialisation process dispatchQueue
are capturing self reference right before it's actual initialisation.
You are running into the concurrency problem
where initialisation of object is necessary before using it.
dispatchQueue
uses closures to provide DispatchWorkItem
and as you know closures captures values surrounding it's scope.
Update
One work around would be to give default values to your properties but I am not sure if that will help you.
Upvotes: 1