UIStackView Disappointments

When working with UIStackView within Interface Builder I would frequently encounter errors that would tell me the an impossible co-efficient could not be reconciled within auto-layout. I fixed this by not using UIStackView. This was a difficult decision to make and only came after losing a few hours to these issues. I had actually argued to target iOS 9 in large part because of my excitement about this new tool; hopefully Apple will fix it in iOS 10. 😞

The aforementioned error:

Cannot find an outgoing row head for incoming head during optimization of variable with near-zero coefficient, which should never happen.

Yet another, more frustrating problem I was hitting involved the reliable crashing of Xcode when working with 4 horizontal stack views within a larger vertical stack view. I lost half a day to this and once again accepted that I would have to pretend UIStackView does not exist.

Someone let me know if they ever fix it. 😒

Swift 2.2 and the Objective-C Runtime

With Swift 2.2 using the Objective-C runtime is a lot easier. An improved way of working with Selectors allows for the ditching of the old 'stringly' typed handling of Selector in Swift and adds the new #selector(Class.method). This new syntax does have it's quirks though:

  • Functions for use as a Selector must be exposed to Objective-C. You can do this by marking the function as @objc like this: @objc func buttonTapped() { … }

  • The Selector must be tied to the class under which it exists. For example, a common use case would be calling removeFromSuperview on each UIView in an array of UIViews. In Objective-C it would look like this: [subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    and now in Swift 2.2, it looks like this: subviews.makeObjectsPerformSelector(#selector(UIView.removeFromSuperview))

The biggest help for my personal needs is the return of accessing the memory address of a variable using the classic &. This stopped working and I noticed it with Swift 2.1, but I don't know when it happened. Now though, we can once again do this:

var associatedKey = "associatedKey"

objc_setAssociatedObject(self, &associatedKey, value, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)

Before 2.2 I was noticing problems with the automatic bridging of a Swift String to an NSString. A Swift String is a struct but accessing the memory address of a variable only works with classes. The reason it would work with a String is because of the automatic bridging to NSString, but this would mean that the memory address of the NSString was different on each use, and so the associated object could not be reliably fetched using the key. Previously I got around this by explicitly marking the key as an NSString, bypassing the bridging. However, this too has been resolved, but I don't know how because from my debugging the memory address is still different each time. If anybody knows what's going on I would genuinely love to know.