0

I have this optimization problem. I have a view in nib that consists of the picture and a label. Here is the way I load it from the nib:

@IBOutlet weak var imageView: UIImageView!
var view: UIView!
let nibName = "customView"

override init(frame: CGRect) {
    super.init(frame: frame)
    setup()
}

public required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setup()
}

func setup() {
    view = loadFromNib()
    view.frame = self.bounds
    imageView.image = CustomView.defaultImage
    addSubview(view)
    setupProfileView()
}

func loadFromNib() -> UIView {
    let bundle = NSBundle(forClass: self.dynamicType)
    let nib = UINib(nibName: nibName, bundle: bundle)
    let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
    return view
}

It takes quite considerable amount of time whenever it loads. My UI is pretty heave on those customViews, I need to be able create around 50 of them and place them around without blocking the mainThread. It takes 170ms to create them using init with frame and 350 more to place them as subviews in my vc. Any suggestions how I can ease the load on the main thread in this case ? Maybe a programmatic approach would be better then the nib one ?

Olexiy Burov
  • 1,007
  • 3
  • 11
  • 22

1 Answers1

1

Just do the actual load in background thread, and once it is done - pass the reference back to the main thread, while showing a spinning wheel or something (if you want and if it is needed):

dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
    // Load your NIB here.

    dispatch_async(dispatch_get_main_queue(), ^{
        // Pass reference to main queue here.
    });
});

This way you will do the heavy lifting in the parallel thread, while keeping the main thread free.

Soberman
  • 2,556
  • 1
  • 19
  • 22
  • Will that actually work ? Cause things don't work out well with frames on the background thread. I'll give it a try and let you know as soon as possible. – Olexiy Burov Oct 18 '15 at 22:26
  • Okay, that did improve things. Is there any way to make it draw faster ? Namely, addSubviews still takes quiet a while. – Olexiy Burov Oct 19 '15 at 00:16
  • Nah, you should add subviews on the main thread, as it is manipulation with interface, which should be always done on main thread. What you can do is load everything you need in the background thread, and then, with one call to main thread add all those subviews (in case you have a lot of NIBs). – Soberman Oct 19 '15 at 09:14
  • Since you are having a lot of them, either show a spinner or something, or do all this before the screen is being shown, like in `viewWillAppear:` or something, to make this wait for subviews not that awkward-looking. – Soberman Oct 19 '15 at 09:16