3

I've just updated my code from Swift 1.2 to Swift 2.1. The project was fully-functioning with previous version of Swift, but now I'm seeing "Ambiguous use of 'init'" errors. Each occurrence of this error seems to be caused by the use of optional arguments in the constructor. I've even managed to reproduce this issue in Xcode Playground with the following simplified code using the same pattern:

class Item : UIView {
    override init(frame: CGRect = CGRectZero) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

let i = Item()             # Ambiguous use of 'init(frame:)'

However, I still don't understand why Swift 2.1 now has a problem with this pattern, or what the alternative should be. I've tried searching for this, but all I've stumbled upon was "ambiguous use" errors for other (non-constructor) methods due to method renaming or signature changing, neither of which is the case here.

Alexander Tsepkov
  • 3,946
  • 3
  • 35
  • 59
  • 1
    This snippet doesn't work in Swift 1.2 either (I just tested). Maybe your real code did, but this part doesn't. – Eric Aya Jan 19 '16 at 14:27
  • odd, looking at the diff now trying to see what else may have changed but not seeing anything else related and I've had no issues building that code before (comparing against pre-swift2 commit). – Alexander Tsepkov Jan 19 '16 at 14:32
  • So after more investigation (wasn't able to test older version of Swift until I set up an older VM), the error Swift 1.2 gives is different. In this particular case Swift 1.2 is trying to call the constructor with coder. I'm not sure why that's not happening in my app itself, as the aDecoder constructor is present there as well and all of the arguments to init are optional so it's not that it has more information. – Alexander Tsepkov Jan 19 '16 at 15:45

1 Answers1

4

It's ambiguous use because when u call let i = Item(), there are 2 options - the init(frame: CGRect = CGRectZero) and the init()

it's better to do something like this:

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

convenience init() {
    self.init(frame: CGRectZero)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
Witterquick
  • 6,048
  • 3
  • 26
  • 50