swift - make init() private for NSObject subclass -
the class fooclass
should allow interaction via sharedinstance
. trying prevent misuse not allowing access init()
of fooclass
.
i have tried few different approaches, none work:
using private keyword:
class fooclass: nsobject { // singleton static let sharedinstance = fooclass() let value: string private override init() { self.value = "asdf" } } // should compile error, not let foo = fooclass()
using @available:
class fooclass: nsobject { // singleton // compile error - "init unavailable. use sharedinstance" static let sharedinstance = fooclass() let value: string @available(*, unavailable, message="use sharedinstance") override init() { self.value = "asdf" } } // compile error - should let foo = fooclass()
i have tried using internal well, still no luck.
update
first version works if move own file, objc version of class still allows init called. ideas?
swift_class("_ttc11swifttoobjc8fooclass") @interface fooclass : nsobject + (fooclass * __nonnull)sharedinstance; @property (nonatomic, readonly, copy) nsstring * __nonnull value; - (nonnull instancetype)init objc_designated_initializer; @end
this answer addresses swift 2. in swift 3 looks access level of method correctly imported swift objective-c , not need marked ns_unavailable
in order disallow being available. of course, there no new
method in swift still need marked ns_unavailable
maintain singleton properly.
your first approach work long class put in own file. access control keyword private
means defined feature available within containing file.
however, said, using swift class in objective-c remove protection private
gives you. believe that's because marked private
not have entry in imported header file generated compiler. init
function inherited nsobject
available because isn't overridden.
the solution found create header file explicitly declares init
function can't called.
swift class:
@objc(fooclass) class fooclass: nsobject { // singleton static let sharedinstance = fooclass() let value: string private override init() { self.value = "asdf" } }
objective-c header:
@interface fooclass (sharedinstance) + (instancetype) new ns_unavailable; - (instancetype) init ns_unavailable; @end
you have block new
because if don't instance of class created through it.
testing:
fooclass* foo = [fooclass sharedinstance]; // here fooclass* foo2 = [[fooclass alloc] init]; // 'init' unavailable fooclass* foo3 = [fooclass new]; // 'new' unavailable
i have rudimentary example project here: sharedinstance project git
Comments
Post a Comment