Reputation: 18729
When directly assigning / implementing a Swift closure it is no problem to access class properties. But when I try to define the closure as class propertie as well, access to other class properties is not possible. Why is this?
Here is an example:
While the closure directly assigned to editorVC.completionBlock
can access the class property tableView
without any problem, the same code within leads to an error when the closure is defined as class property editorCompletionBlock
:
class MyViewController: UIViewController {
@IBOutlet var tableView: UITableView!
func showEditor(withData: String) {
let editorVC = EditorViewController()
// Directly assign closure - Works without any problem
editorVC.completionBlock = { (result) in
self.tableView.reloadData()
doSomething(withResult: result)
// ...
}
present(editorVC, animated: true, completion: nil)
}
// Define closure as class property ==> Error
let editorCompletionBlock: EditorCompletionBlock = { (resut) in
// ERROR: Value of type '(MyViewController) -> () -> MyViewController' has no member 'tableView'
self.tableView.reloadData()
doSomething(withResult: result)
// ...
}
}
typealias EditorCompletionBlock = (String) -> Void
class EditorViewController: UIViewController {
var completionBlock: EditorCompletionBlock?
func closeEditor(withResult result: String) {
completionBlock?(result)
}
}
Upvotes: 0
Views: 220
Reputation: 578
Solution 1:
place your editorCompletionBlock
in viewDidLoad
(:_) and it should work like charm:
class MyViewController: UIViewController {
@IBOutlet var tableView: UITableView!
func showEditor(withData: String) {
let editorVC = EditorViewController()
editorVC.completionBlock = { (result) in
self.tableView.reloadData()
}
present(editorVC, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
let editorCompletionBlock: EditorCompletionBlock = { (resut) in
self.tableView.reloadData() ///should work :)
}
}
}
typealias EditorCompletionBlock = (String) -> Void
class EditorViewController: UIViewController {
var completionBlock: EditorCompletionBlock?
func closeEditor(withResult result: String) {
completionBlock?(result)
}
}
Solution 2:
Or you can just declare your closure as lazy
:
lazy var editorCompletionBlock: EditorCompletionBlock = { (result)
in
self.tableView.reloadData()
doSomething(withResult: result)
}
Upvotes: 1
Reputation: 24341
Reason:
You can't access self
until the initialization process of a type is completed.
In your code, editorCompletionBlock
is a stored property and you're trying to access self.tableView
inside it. This is the reason it is giving compile time error.
Solution:
Instead, make editorCompletionBlock
as a lazy
property to get that working.
lazy var editorCompletionBlock: EditorCompletionBlock = { (result) in
self.tableView.reloadData()
doSomething(withResult: result)
}
Upvotes: 3