2

I am trying to add a stored property to an NSBezierPath by subclassing it. However the following code crashes Playground:

import Cocoa

class MyNSBezierPath: NSBezierPath {

    private var someProperty: Bool

    override init() {
        someProperty = false
        super.init()
    }

    required init?(coder aDecoder: NSCoder) {
        self.someProperty = false
        super.init(coder: aDecoder)
    }
}

// the following line causes the Playground to fully crash
let somePath = MyNSBezierPath()

The Playground error (below) seems to indicate a problem with NSCoder but I thought that just passing the call through to the superclass like this would be OK. What am I doing wrong?

UNCAUGHT EXCEPTION (NSInvalidUnarchiveOperationException): 
*** - [NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class
(__lldb_expr_22.MyNSBezierPath) for key (root); 
the class may be defined in source code or a library that is not linked
UserInfo: { "__NSCoderInternalErrorCode" = 4864;}
Hints: None
Martin CR
  • 1,250
  • 13
  • 25
  • 1
    Hmmm... reading [this other answer](http://stackoverflow.com/questions/29867782/uibezierpath-subclass-initializer) it sounds like subclassing NSBezierPath may be a **bad** idea. Perhaps I'll have to go with a wrapper - which is a shame because it makes the code less legible :( – Martin CR Jul 03 '16 at 20:42
  • That is one nasty crash too... I'm a bit surprised Xcode doesn't handle it better. – l'L'l Jul 03 '16 at 21:09
  • You and me both... – Martin CR Jul 03 '16 at 21:49

1 Answers1

1

You could create an extension to add a method to NSBezierPath.

#if os(iOS)
typealias OSBezierPath = UIBezierPath
#else
typealias OSBezierPath = NSBezierPath

extension OSBezierPath {
    func addLineToPoint(point:CGPoint) {
        self.lineToPoint(point)
    }
}
#endif

Or you could use OSBezierPath by calling lineToPoint by using initializer.

#if os(iOS)
class OSBezierPath: UIBezierPath {
    func lineToPoint(point:CGPoint) {
        self.addLineToPoint(point)
    }
}
#else
typealias OSBezierPath = NSBezierPath
#endif

Some code from Apple Swift

It's not the same function of course but I'm showing you Apple using typealias OSBezierPath = UIBezierPath

EDIT: You can create a set Method and use it within your init-Method:

class SomeClass {
var someProperty: AnyObject! {
    didSet {
        //do something
    }
}

init(someProperty: AnyObject) {
    setSomeProperty(someProperty)
}

func setSomeProperty(newValue:AnyObject) {
    self.someProperty = newValue
}
}
Edison
  • 11,881
  • 5
  • 42
  • 50
  • Yes but they're all related incase your issue is from any one of those areas. See my new updated answer. – Edison Jul 03 '16 at 22:14
  • please give a concrete example of how what you propose, can be used to add a stored property by subclassing NSBezierPath. – Martin CR Jul 21 '16 at 09:08