Ive have a large UIView in the app Im working on right now, with loads of IBOutlets. There are two instances of charts, various labels, textfields, etc. All are linked to my UIView via explicitly unwrapped optionals, as Apple advise, like this :
@IBOutlet weak var detailBox: UIView!
Now at the same time as this view is being loaded, I have downloads happening in the background. Large downloads, of XML, as it happens. When each download finishes, I have a parser that is taking that XML apart and turning it into useful local objects. Eg :
convenience required init(xml: AEXMLDocument, patient: Patient?, externalContext: NSManagedObjectContext?) {
self.init()
//print("------- get EOBS info by location -------")
//print("XML : \(xml.xml)")
self.isValid = true
You can see the start of the parser class there. Those commented print statements are what is breaking my UIView. How you ask? Well Im attempting to print out what are large chunks of XML. My UIView loading work must happen on the main thread, and that main thread is being held up by the printing process, which takes several seconds.
Meanwhile, my UIView is being asked to render the chart. My IBOutlets are explicitly unwrapped optionals, and Swift fans will know that if you try and use an implicitly unwrapped optional when it is nil, the result is in instant crash. And that is what happened in my case. As Curtis Herbert points out on his blog, doing as Apple suggests and always using implicitly unwrapped optionals for UIView IBOutlets is not always a good idea.
My immediate solution? Removing the print statements got rid of the crash, as the main thread had plenty of time to render the view before using my unwrapped properties. But in general this doesnt feel very safe - so the real fix here would be to use optionals, and unwrap as you go. Its more work, but its safer.
No comments:
Post a Comment