42

I have run into this problem a few times while porting Objective-C code to Swift. Say I have the following code:

dispatch_async(dispatch_get_main_queue()) {
    self.hostViewController?.view.addSubview(self.commandField)
}

This will result in an error, underlining the entire dispatch_async call, offering:

Could not find member 'addSubview'

I assume this is an error that has not yet been properly implemented because if I put the addSubview call outside the dispatch_async block, the project builds fine. Initially I assumed it may have something to do with capturing self in the block. However, inserting [unowned self] in results in the same error, as does [weak self] in (after the appropriate ! unwrap operators have been inserted).

How can I get dispatch_async blocks to work in Swift that need to capture self?

2 Answers 2

65

You should condition spinning off this action on the non-nullity, not test for it after you've already initiated it:

if let hostView = self.hostViewController?.view {
    DispatchQueue.main.async {
         hostView.addSubview(self.commandField)
    }
} else {
    // handle nil hostView 
}

You should never unwrap an optional outside of an if let, or testing it first. Doing this should also resolve yer weak self issue.

Sign up to request clarification or add additional context in comments.

2 Comments

Ah that works, thanks! So is the compiler complaining that it can't deterministically unwrap hostController? inside the block? Or is there something else going on here?
It's because the expression self.hostViewController?.view returns an object of type NSView?, not NSView. Optional chains always have to be checked and the result either has to be letted or forced.
13

The dispatch_async syntax has changed with Swift 3:

DispatchQueue.main.async { 
    hostView.addSubview(self.commandField)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.