Reputation: 2538
I currently have a UITableView that holds a list of events. Each event has a button where the user can press it to get access to a larger view of a photo associated with the event. I have the UIButton connected and set up but I'm having a hard time setting the image in the new window. Here is my function:
func largeMap(sender: UIButton!) {
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let manager = NSFileManager.defaultManager()
self.performSegueWithIdentifier("largeMapView", sender: self)
println(sender.tag.description)
println(documentsPath+"/Flight"+(sender.tag.description)+"/Map.png")
if let image = UIImage(data: manager.contentsAtPath(documentsPath+"/Flight"+(sender.tag.description)+"/Map.png")!) {
largeMapView.image = image
}
}
When I run the app, it crashes at largeMapView.image = image and gives me "fatal error: unexpectedly found nil while unwrapping an Optional value". I've checked and the path for the image is correct and it is accessing the image but it's not able to set it to the UIImageView. I have the UIImageView outlet set at the top of the class. Why is this happening? I've set UIImageView's in this manner before but it just won't work now.
Upvotes: 0
Views: 1382
Reputation: 536028
Basically the problem is that you are using exclamation marks. Exclamation marks are never safe! They can be a "bad smell", a danger signal - and in your code, that's just what they are.
(1)
I have the UIImageView outlet set at the top of the class.
But you do not show how it is set. You do not show what largeMapView
is or how it is declared. The declaration might look like this:
@IBOutlet var largeMapView : UIImageView!
If so, that is bad - that is an implicitly unwrapped optional, which means it might be nil. This could be the source of your problem. By using a conditionally unwrapped optional you are covering up the problem - until you try to set into nil, and then you crash. If it is never being set properly, that's the reason for the crash.
(2)
Along the same same lines, the rest of your code, too, should not force-unwrap Optionals (using !
postfix operator) unless you know for certain that they can never be nil. Rewrite like this so that every Optional is unwrapped conditionally and safely:
if let d = manager.contentsAtPath(documentsPath+"/Flight"+(sender.tag.description)+"/Map.png") {
if let image = UIImage(data: d) {
largeMapView.image = image
}
}
This way, if contentsAtPath
fails or UIImage(data:)
fails, nothing will happen - you won't set your image - but at least you won't crash. And you can use stepping in the debugger to figure out where you are failing. - But even this will not save you if the problem is that largeMapView
is a nil implicitly unwrapped Optional.
Upvotes: 2