xcode - Subclassing class that only expose convenience init -
i want subclass uitableviewrowaction class declared follow :
class uitableviewrowaction : nsobject, nscopying { convenience init(style: uitableviewrowactionstyle, title: string!, handler: (uitableviewrowaction!, nsindexpath!) -> void) var style: uitableviewrowactionstyle { } var title: string! @nscopying var backgroundcolor: uicolor! // default background color dependent on style @nscopying var backgroundeffect: uivisualeffect? }
i subclass override convenience init present here , call super convenience init.
here want :
public class mysubclass : uitableviewrowaction { let handler : (uitableviewrowaction!, nsindexpath!) -> void public init(style: uitableviewrowactionstyle, title: string!, handler: (uitableviewrowaction!, nsindexpath!) -> void) { self.handler = handler super.init(style: style, title: title, handler: handler) // error == must call designated initializer of superclass 'uitableviewrowaction' } }
i want in order expose handler readonly property able unit test handler think should do.
so problem super class don't expose handler passed init method , there no way set outside of init method.
i don't know if answer whole lot different yours, ran similar problem while trying unit test. feels little cleaner; subjective. can use set_associatedobject (and get_associatedobject) , small private actiontrigger wrapper class allow triggering action within unit test.
import uikit import objectivec var actiontriggerhandle: uint8 = 0 private class actiontrigger { private var handler: (uitableviewrowaction!, nsindexpath!) -> () private var action: uitableviewrowaction private init(action: uitableviewrowaction, handler: (uitableviewrowaction!, nsindexpath!) -> void) { self.handler = handler self.action = action } private func trigger(indexpath: nsindexpath) { handler(action, indexpath) } } public extension uitableviewrowaction { public convenience init(title: string!, style: uitableviewrowactionstyle, exposedhandler: (uitableviewrowaction!, nsindexpath!) -> void) { self.init(style: style, title: title, handler: exposedhandler) var actiontrigger = actiontrigger(action: self, handler: exposedhandler) objc_setassociatedobject(self, &actiontriggerhandle, actiontrigger, objc_associationpolicy(objc_association_retain_nonatomic)) } public func trigger(indexpath:nsindexpath) { if let storedactiontrigger = objc_getassociatedobject(self, &actiontriggerhandle) as? actiontrigger { storedactiontrigger.trigger(indexpath) } } }
Comments
Post a Comment