4

I'm attempting to create a custom NSTextFieldCell subclass in Swift (Xcode Beta 5), with the following code:

class CustomHighlightTextFieldCell : NSTextFieldCell {

    required init(coder aCoder: NSCoder!) {
        super.init(coder: aCoder)
    }

    init(imageCell anImage: NSImage!) {
        super.init(imageCell: anImage)
    }

    init(textCell aString: String!) {
        super.init(textCell: aString)
    }
}

However, I receive compilation errors on the 2nd and 3rd init() declarations:

/Users/Craig/projects/.../CustomHighlightTextFieldCell:8:40: Invalid redeclaration of 'init(imageCell:)'
/Users/Craig/projects/.../CustomHighlightTextFieldCell.swift:17:5: 'init(imageCell:)' previously declared here

/Users/Craig/projects/.../CustomHighlightTextFieldCell:7:39: Invalid redeclaration of 'init(textCell:)'
/Users/Craig/projects/.../CustomHighlightTextFieldCell.swift:21:5: 'init(textCell:)' previously declared here

While there are some strange compiler bugs here (I'm getting the usual "SourceKitService Terminated, Editor functionality temporarily limited." message), it seems like I'm missing something in my method overriding - but I can't tell what.

I was under the assumption the named parameters, or at least the parameter types, would indicate that there are three different init() methods here, but apparently I'm missing a key piece of the puzzle.

Edit: If I add override to the 2nd and 3rd init() methods, I have a separate issue:

required init(coder aCoder: NSCoder!) {
    super.init(coder: aCoder)
}

override init(imageCell anImage: NSImage!) {
    super.init(imageCell: anImage)
}

override init(textCell aString: String!) {
    super.init(textCell: aString)
}

This new issue (simply invoked by adding the two override keywords) seems to almost contradict the original.

/Users/Craig/projects/.../CustomHighlightTextFieldCell.swift:17:14: Initializer does not override a designated initializer from its superclass
/Users/Craig/projects/.../CustomHighlightTextFieldCell.swift:21:14: Initializer does not override a designated initializer from its superclass
Craig Otis
  • 31,257
  • 32
  • 136
  • 234

2 Answers2

5

It would seem that your declarations (with override) should be sufficient, however, they seem to need the @objc declarations as well. This works:

class CustomHighlightTextFieldCell : NSTextFieldCell {

    required init(coder aCoder: NSCoder!) {
        super.init(coder: aCoder)
    }

    @objc(initImageCell:)
    override init(imageCell anImage: NSImage!) {
        super.init(imageCell: anImage)
    }

    @objc(initTextCell:)
    override init(textCell aString: String!) {
        super.init(textCell: aString)
    }
}
Grimxn
  • 22,115
  • 10
  • 72
  • 85
  • This works great, thanks! Sounds like I've got some reading to do regarding `@objc` - this sounds like a bug? – Craig Otis Aug 12 '14 at 11:47
  • Well, from reading the Xcode docs it gives the Swift declarations exactly as you had them, without the @objc patterns, so it looks like it might be a bug. – Grimxn Aug 12 '14 at 12:00
  • I reported that as bug but after one month I even have no feedback. Somewhere I read about more than 1300 bugs with Swift. Admittedly it's better than Obj-C but it still smells. Compared to what this company earns per second this compiler is - well, I should silent down. – qwerty_so Dec 11 '14 at 15:40
  • Another great tip who's exact implementation is not found here: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_86 – Morkrom Dec 15 '14 at 22:33
3

As you see, you have the corresponding super.init(xxx) in the functions which means you are overriding the functions. So just add the override keyword.

override init(imageCell anImage: NSImage!) {
    super.init(imageCell: anImage)
}

override init(textCell aString: String!) {
    super.init(textCell: aString)
}
Nate Cook
  • 92,417
  • 32
  • 217
  • 178
ZYiOS
  • 5,204
  • 3
  • 39
  • 45