4

I have a default image in viewItem to make sure that it is working, it shows on the detail view of the splitview.

@IBOutlet weak var ImageView: UIImageView!

var imageCache = [String: UIImage]()

override func viewDidLoad() {
    super.viewDidLoad()
    self.configureView()
}

func configureView() {
    if let detail: AnyObject = self.detailItem {
        if let label = self.detailDescriptionLabel {
            let dict = detail as [String: String]
            label.text = ""
            let s = dict["result"]
            let vr = NString(string: s!)
            let vrd = vr.doubleValue
            let value = ceil(vrd*20)
            let valueString = String(format: "%.0f", value)

            vresult.text = "\(valueString)%"

            getPic(dict)  // <---- trouble maker

            fitem.hidden = false
            ritem.hidden = false
        }
    } else {
        navigationController?.popViewControllerAnimated(true)
    }
}

func getPic(item: [String: String]) {
    var chachedImage = self.imageCache[item["image"]!]

    println(item["image"]) // <-- prints out the url

    if cachedImage == nil {
        var imgUrl = NSURL(string: item["image"]!)
        let request: NSURLRequest = NSURLRequest(URL: imgUrl!)
        NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {( reponse: NSURLResponse!, data: NSData!, error; NSError!) -> Void in
            if error == nil {
                cachedImage = UIImage(data: data)

                println("got here no problem") // <-- prints out

                self.imageCache[item["image"]!] = cachedImage

                println(self.imageCache) // <-- prints reference OK

                dispatch_async(dispatch_get_main_queue(), {
                    self.ImageView.image = cachedImage  // <---- offender
                })
            } else {
               println("Error: \(error.localizedDescription)")
            }
        })
    } else {
        dispatch_async(dispatch_get_main_queue(), {
            self.ImageView.image = cachedImage
        })
    }
}

ImageView is coming up nil every time.

fatal error: unexpectedly found nil while unwrapping an Optional value

but the default image shows. I've moved this out of the dispatch and even tried setting it straight from the viewDidLoad() always errors. It used to be a UIWebView and worked perfectly except that it would not cache anything. Since loading these images is a lot of work, I thought caching would be good, I've got caching working for thumbnails in the MASTER view.

Jason G
  • 2,395
  • 2
  • 24
  • 34
  • What do you mean 'ImageView is coming up nil every time'? It's an IBOutlet so it's either nil at ViewDidLoad or defined, and stays that way. If it's nil and can't be referenced from a closure (or ViewDidLoad as you indicated), what happens if you remove the weak attribute (temporarily)? Do you set a breakpoint to see when it's defined (non-nil) if ever, before you access it? Maybe at lldb prompt type 'p ImageView'? BTW: By convention people often like to distinguish between reference variables and class names by keeping the former lowercase first letter and latter capitalized. – clearlight Feb 04 '15 at 21:47
  • i think you got it there at the end, i changed the name to start with new (lowercase) and now it works! – Jason G Feb 04 '15 at 21:51

5 Answers5

6

It may be because of how your instaciating your viewcontroller.

let vc = MyViewController()

Something like this wont work. You're creating the VC without actually giving the storyboard a chance to link the IBOutlets. Instead use

storyboard.instantiateViewControllerWithIdentifier(identifier: String)

You may need to get reference to the storyboard using

let storyboard = UIStoryboard(name: name, bundle: NSBundle.mainBundle())

Hope this helps :)

Jordankid93
  • 71
  • 1
  • 4
1

Changing your variable name shouldn't make any difference except for readibility/maintainability unless there's a namespace conflict (good to understand why/where that might be happening). Also I was wondering - you made the IBOutlet'ed varable weak. When the last remaining strong ref to the object goes away, the weak references to the object are set nil by the runtime/garbage collector automatically. (Look up that section of the Swift documentation if you're not solid about it).

Maybe you should check your classes and controllers by adding deinit { println(,"function name deallocated' }. Between your use of weak and improved behavior seen when you change the variable name, it seems like there might be some weird (buggy) interactions going on in your app itself.

clearlight
  • 12,255
  • 11
  • 57
  • 75
0

Well silly me. I've been working on this for a few days, I got the great idea to try and change the name, and it worked. I tried changing it back and it broke, apparently you can't use ImageView as a variable!

Jason G
  • 2,395
  • 2
  • 24
  • 34
  • That would be a very weird and unexpected bug in Apple's code. I'd suspect your code first, and namespace conflicts vs. weak reference and object deallocations as mentioned in my 'answer'. – clearlight Feb 04 '15 at 22:14
0

In my case was because I was using a nib and didn't register it.

Once I did registered it, it worked

Frakcool
  • 10,915
  • 9
  • 50
  • 89
0

My case Was Different I used

awakeFromNib()

instead of

viewDidLoad()

.

SunGoku
  • 28
  • 5