I wrote class Vehicle in Vehicle.swift and inherited it in another class Bicycle in Bicycle.swift. But Xcode 6.1 reported an compile error: initializer does not override a designated initializer from its superclass.
Vehicle.swift:
import Foundation
public class Vehicle {
var numberOfWheels: Int?
var description: String {
return "\(numberOfWheels) wheel(s)"
}
}
Bicycle.swift:
import Foundation
public class Bicycle: Vehicle {
override init() {
super.init()
numberOfWheels = 2
}
}
Those codes are from Apple iOS Developer Library. Link: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-XID_324
When in the same .swift file, they can pass the compile. Only do not work in different files. Is this a bug of swift?
It seems, Default Initializer is invisible from other files, as if it's declared as private init() {}.
I've not found any official documents about this behavior, though. I think it's a bug.
Anyway, explicit init() declaration solves the problem.
public class Vehicle {
init() {} // <- HERE
var numberOfWheels: Int?
var description: String {
return "\(numberOfWheels) wheel(s)"
}
}
OR as #rdelmar says in comment, explicit initial value of numberOfWheels also works:
public class Vehicle {
var numberOfWheels: Int? = nil
var description: String {
return "\(numberOfWheels) wheel(s)"
}
}
Bicycle is not a public class. Code from Apple's Library:
class Bicycle: Vehicle {
override init() {
super.init()
numberOfWheels = 2
}
}
Related
I am having a public class in a different code like this -
public class Person {
public required init() {}
}
This class is in a framework and cannot be modified.
Now the problem is I have been told to inherit from this class and create a singleton object of the new class
public class Jon: Person {
public static var shared: Jon = Jon()
required init() {}
}
But the required init is letting users create multiple instances of the class Jon.
Can anybody suggest on how to do this in swift 4.
I found a solution to achieve this. Look into my solution hopefully it will serve your purpose.
public class ParentClass {
public required init() {}
}
class SubClass: ParentClass {
static let sharedInstance = SubClass(foo: "")
#available(*, unavailable)
required init() { }
//You can change the init parameter as per your requirement
private init(foo: String) {
super.init()
//Write your initialization code
}
}
If you dont want to pass any argument to the init you can do something like this.
private init(_ foo: String? = nil) {
super.init()
//Write your initialization code
}
Now you initialize your object without passing any argument like
static let sharedInstance = SubClass()
One solution is to use Composition rather than Inheritance as the design solution. Since the Person object is supposed to be singleton as well we make it immutable and initialise it in the private init method using the required init
public class Jon {
static let instance = Jon()
private init() {
person = Person()
}
public let person: Person
}
And it can be used like this (with a name property for instance)
var jon = Jon.instance
jon.person.name = "John"
or Person could be made private and computed properties added to the singleton class
public class Jon {
static let instance = Jon()
private init() {
person = Person()
}
private let person: Person
var name: String? {
get { return person.name }
set { person.name = newValue}
}
}
and then the name property is accessed directly
var jon = Jon.instance
jon.name = "John"
I have one class whose methods and properties are exported using JSExport. In normal cases, it works well. But if the property is the type of some inner class, then it can not be accessed from javascript.
Following are the classes i am using:
Person.swift
import Foundation
import JavaScriptCore
#objc
protocol PersonJavaScritMethod : JSExport {
var testProperty : OuterClassPersonal.Personal? { get set }
func sayHello(name1:String)
}
class Person : NSObject, PersonJavaScritMethod {
var name : String!
var testProperty:OuterClassPersonal.Personal?
init(name:String) {
testProperty = OuterClassPersonal.Personal()
super.init()
self.name = name
}
class func create(name : String) -> Person {
return Person(name: name)
}
func sayHello(name1:String) {
println("Hello \(name) \(name1)")
}
}
Personal.swift
import Foundation
import JavaScriptCore
#objc
protocol PersonalJavaScritMethod : JSExport {
func getNNN()
}
class OuterClassPersonal:NSObject,JSExport{
class Personal:NSObject,PersonalJavaScritMethod {
func getNNN(){
println("Hip Hip Hurray")
}
}
}
JavaScript.swift
import Foundation
import JavaScriptCore
class Javascript {
let context = JSContext()
func evaluateScript() {
context.exceptionHandler = { context, exception in
println("❌ Error in Javascript: \(exception) ");
}
var p1:Person = Person(name: "Luitel")
context.globalObject.setObject(p1, forKeyedSubscript: "Person1")
context.evaluateScript("Person1.sayHello('sdf') \n ")
var result = context.evaluateScript("Person1.testProperty.getNNN() \n")
println("\(result.toString())")
}
}
When i run the evaluateScript() method, i get the output as the following in console,
Hello Luitel sdf ❌ Error in Javascript: TypeError: undefined is not a
function (evaluating 'Person1.testProperty.getNNN()')
undefined
i want to access the method getNNN() of Personal Class. Here, if getNNN() is the method of OuterClassPersonal class and OuterClassPersonal implements PersonalJavaScriptMethod, it works properly.
The Question is, How can i access method of internal class "Personal" from Javascript?
Seems there is no way exporting inner class functions to javascript. I moved the inner class (Personal) out and created independent class and it worked.
I am trying to write a simple property observer that can be used to see updates to a type - ie a public form of didSet. The basic implementation was easy enough, but I then wanted to use it for both strong (value and reference) types and weak (reference) types. The motivation for the latter was to serve as a lazy caching strategy wherein a shared resource would remain in use until the last observer freed it, whereupon it would query for the value again - generally from NSURLCache, but otherwise a remote server. In short, I wanted a transparent multi-tiered cache.
I have done things like this in C++, where I had stored either a type, or a type wrapped in smart pointer, through the use of a trait with typedef's for Type, StoredType, etc, so I could pass a trait for value types, or a trait for ref-counted pointer types etc.
From my understanding of Swift though, the unowned and weak modifiers are applied to the property and not to the type per se, so you can't for example do something like:
typealias StorageType = weak T
To work around this limitation, I abstracted my generic type T to always use a storage container, where the container could use either the direct type, or a weak reference to what would have to be a class-based AnyClass type. (This effort itself was cludged by the fact that you can't override assignment operators and that conversion functions were abandoned in the early betas)
Frustratingly, I ran into compiler bugs where it just segfaulted.
Given that I can't be the first person to have tried to solve this type of problem, has anybody found a clean way through it? Obviously the segfault is just another compiler bug, but perhaps there is a simpler solution?
For reference, my code (with the segfault inducing code in comments) is:
public class ObserverSubscription : Hashable {
// public (hashable)
public var hashValue: Int { return token }
// private
private init(token:Int, observable:ObservableProtocol) {
self.token = token
self.observable = observable
}
deinit {
self.observable.unsubscribe(self)
}
private var token:Int
private var observable:ObservableProtocol
}
public func ==(lhs: ObserverSubscription, rhs: ObserverSubscription) -> Bool {
return lhs.hashValue == rhs.hashValue
}
public protocol Storage {
typealias T
typealias StorageType
init(t:StorageType)
var element:StorageType { get set }
}
public class Weak<Type:AnyObject> : Storage {
typealias T = Type
typealias StorageType = T?
public required init(t:StorageType) { element = t }
public weak var element:StorageType
}
public class Strong<Type> : Storage{
typealias T = Type
typealias StorageType = T
public required init(t:StorageType) { element = t }
public var element:StorageType
}
public protocol ObservableProtocol {
func unsubscribe(subscription:ObserverSubscription)
}
public class Observable<T, Container:Storage where T == Container.T> : ObservableProtocol {
public typealias StorageType = Container.StorageType
public typealias Subscription = ObserverSubscription
public typealias ChangeNotifier = (Container.StorageType) -> ()
public init(_ t:Container.StorageType) {
self.value = Container(t:t)
}
public init(_ source:Observable<T, Container>) {
self.value = Container(t:source.value.element)
}
public func subscribe(notifier:ChangeNotifier) {
let subscription = Subscription(token: token++, observable: self)
subscriptions[subscription] = notifier
}
public func unsubscribe(subscription:Subscription) {
subscriptions.removeValueForKey(subscription)
}
public func subscription(notifier:(Container.StorageType) -> ()) -> Subscription {
let subscription = Subscription(token: token++, observable: self)
subscriptions[subscription] = notifier
return subscription
}
public func update(t:Container.StorageType) {
self.value.element = t
}
public private(set) var value:Container { didSet {
for n in subscriptions.keys {
self.subscriptions[n]!(self.value.element)
}}}
private var token:Int = 0
private var subscriptions: [Subscription: ChangeNotifier] = [:]
}
public class ValueObserver<T> : Observable<T, Strong<T>> {
override init(_ t:StorageType) {
super.init(t)
}
}
// dare ye segfault?
//public class WeakObserver<T:AnyObject> : Observable<T, Weak<T>> {
// override init(_ t:StorageType) {
// super.init(t)
// }
//}
My actual code was a little more involved, I derived a lazily loading class from the observer, but this too, induced a segfault:
//public class LazyLoader<T:AnyObject> : Observable<T, Weak<T>> {
//
// override init(_ t:StorageType) {
// super.init(t)
// }
//
// // do lazy loading here
//}
I have tested the observer in isolation, outside of the missing-trait work around, but has been many characters since I tested it. My goal at this point is to find a solution that compiles (and which could hopefully be simpler)
Thanks!
For example a have a first class
public class MyBaseButton: UIButton {
public var weight: Double = 1.0
public var text: String? {
get {
return self.titleForState(.Normal)
}
set {
return self.setTitle(newValue, forState: .Normal)
}
}
}
And inherited class:
public class SomeButton: SomeBaseButton {
override public var text: String? = "text"
override public var weight: Double = 2.0
}
So, the logic is that SomeClass define own text and weight.
But I'm getting an errors:
For text: "Cannot override with a stored property 'text'"
For weight: "Cannot override with a stored property 'weight'"
Interestingly this works just fine in pure Swift classes. For example, this works as expected:
public class FooButton {
public var weight: Double = 1.0
}
public class BarButton: FooButton {
override public var weight: Double = 2.0
}
The reason it does not work for you is because you are working with Objective-C classes: since UIButton is an Objective-C class, all its subclasses will be too. Because of that, the rules seem to be a bit different.
Xcode 6.3 is actually a bit more informative. It shows the following two errors:
Getter for "weight" overrides Objective-C method "weight" from superclass "FooButton"
Setter for "weight" overrides Objective-C method "setWeight:" from superclass "Foobutton"
Since the following does work ...
public class BarButton: FooButton {
override public var weight: Double {
get {
return 2.0
}
set {
// Do Nothing
}
}
}
... my guess is that these methods are simply not synthesized correctly.
I wonder if this is a compiler bug. Or a shortcoming. Because I think it could handle the case.
Maybe the Swift designers thought that in case of overriding weight you could also simply set it to a different value in your initializer. Hm.
In addition, if someone wants to override property to have dynamic effect, see KVO
class MyClass: NSObject {
var date = NSDate()
}
class MyChildClass: MyClass {
dynamic override var date: NSDate {
get { return super.date }
set { super.date = newValue }
}
}
In the above you have a getter and a setter.
When you override it, you are just assigning it a value.
Instead set up the setter and getter as you have above.
var _text:Text
override public var text: String? {
get {
return _text
}
set {
_text = newValue
}
}
I ran into this issue when trying to override the NSPredicateRowEditor templateViews property in Swift 3.
Superclass property to override:
open var templateViews: [NSView] { get }
Override like so:
class CustomRowTemplate: NSPredicateEditorRowTemplate {
override var templateViews: [NSView] {
get {
let templateViews = super.templateViews
// custom subclass work goes here
return templateViews
}
//set {
// Superclass property is `get` only, other properties might need a setter
//}
}
}
This is a relatively common design pattern:
https://stackoverflow.com/a/17015041/743957
It allows you to return a subclass from your init calls.
I'm trying to figure out the best method of achieving the same thing using Swift.
I do know that it is very likely that there is a better method of achieving the same thing with Swift. However, my class is going to be initialized by an existing Obj-C library which I don't have control over. So it does need to work this way and be callable from Obj-C.
Any pointers would be very much appreciated.
I don't believe that this pattern can be directly supported in Swift, because initialisers do not return a value as they do in Objective C - so you do not get an opportunity to return an alternate object instance.
You can use a type method as an object factory - a fairly contrived example is -
class Vehicle
{
var wheels: Int? {
get {
return nil
}
}
class func vehicleFactory(wheels:Int) -> Vehicle
{
var retVal:Vehicle
if (wheels == 4) {
retVal=Car()
}
else if (wheels == 18) {
retVal=Truck()
}
else {
retVal=Vehicle()
}
return retVal
}
}
class Car:Vehicle
{
override var wheels: Int {
get {
return 4
}
}
}
class Truck:Vehicle
{
override var wheels: Int {
get {
return 18
}
}
}
main.swift
let c=Vehicle.vehicleFactory(4) // c is a Car
println(c.wheels) // outputs 4
let t=Vehicle.vehicleFactory(18) // t is a truck
println(t.wheels) // outputs 18
The "swifty" way of creating class clusters would actually be to expose a protocol instead of a base class.
Apparently the compiler forbids static functions on protocols or protocol extensions.
Until e.g. https://github.com/apple/swift-evolution/pull/247 (factory initializers) is accepted and implemented, the only way I could find to do this is the following:
import Foundation
protocol Building {
func numberOfFloors() -> Int
}
func createBuilding(numberOfFloors numFloors: Int) -> Building? {
switch numFloors {
case 1...4:
return SmallBuilding(numberOfFloors: numFloors)
case 5...20:
return BigBuilding(numberOfFloors: numFloors)
case 21...200:
return SkyScraper(numberOfFloors: numFloors)
default:
return nil
}
}
private class BaseBuilding: Building {
let numFloors: Int
init(numberOfFloors:Int) {
self.numFloors = numberOfFloors
}
func numberOfFloors() -> Int {
return self.numFloors
}
}
private class SmallBuilding: BaseBuilding {
}
private class BigBuilding: BaseBuilding {
}
private class SkyScraper: BaseBuilding {
}
.
// this sadly does not work as static functions are not allowed on protocols.
//let skyscraper = Building.create(numberOfFloors: 200)
//let bigBuilding = Building.create(numberOfFloors: 15)
//let smallBuilding = Building.create(numberOfFloors: 2)
// Workaround:
let skyscraper = createBuilding(numberOfFloors: 200)
let bigBuilding = createBuilding(numberOfFloors: 15)
let smallBuilding = createBuilding(numberOfFloors: 2)
Since init() doesn't return values like -init does in Objective C, using a factory method seems like the easiest option.
One trick is to mark your initializers as private, like this:
class Person : CustomStringConvertible {
static func person(age: UInt) -> Person {
if age < 18 {
return ChildPerson(age)
}
else {
return AdultPerson(age)
}
}
let age: UInt
var description: String { return "" }
private init(_ age: UInt) {
self.age = age
}
}
extension Person {
class ChildPerson : Person {
let toyCount: UInt
private override init(_ age: UInt) {
self.toyCount = 5
super.init(age)
}
override var description: String {
return "\(self.dynamicType): I'm \(age). I have \(toyCount) toys!"
}
}
class AdultPerson : Person {
let beerCount: UInt
private override init(_ age: UInt) {
self.beerCount = 99
super.init(age)
}
override var description: String {
return "\(self.dynamicType): I'm \(age). I have \(beerCount) beers!"
}
}
}
This results in the following behavior:
Person.person(10) // "ChildPerson: I'm 10. I have 5 toys!"
Person.person(35) // "AdultPerson: I'm 35. I have 99 beers!"
Person(35) // 'Person' cannot be constructed because it has no accessible initializers
Person.ChildPerson(35) // 'Person.ChildPerson' cannot be constructed because it has no accessible initializers
It's not quite as nice as Objective C, since private means all the subclasses need to be implemented in the same source file, and there's that the minor syntax difference Person.person(x) (or Person.create(x) or whatever) instead of simply Person(x), but practically speaking, it works the same.
To be able to instantiate literally as Person(x), you could turn Person into a proxy class which contains a private instance of the actual base class and forwards everything to it. Without message forwarding, this works for simple interfaces with few properties/methods but it gets unwieldy for anything more complex :P
I think actually the Cluster pattern can be implemented in Swift using runtime functions. The main point is to replace the class of your new object with a subclass when initializing. The code below works fine though I think more attention should be paid to subclass' initialization.
class MyClass
{
var name: String?
convenience init(type: Int)
{
self.init()
var subclass: AnyClass?
if type == 1
{
subclass = MySubclass1.self
}
else if type == 2
{
subclass = MySubclass2.self
}
object_setClass(self, subclass)
self.customInit()
}
func customInit()
{
// to be overridden
}
}
class MySubclass1 : MyClass
{
override func customInit()
{
self.name = "instance of MySubclass1"
}
}
class MySubclass2 : MyClass
{
override func customInit()
{
self.name = "instance of MySubclass2"
}
}
let myObject1 = MyClass(type: 1)
let myObject2 = MyClass(type: 2)
println(myObject1.name)
println(myObject2.name)
protocol SomeProtocol {
init(someData: Int)
func doSomething()
}
class SomeClass: SomeProtocol {
var instance: SomeProtocol
init(someData: Int) {
if someData == 0 {
instance = SomeOtherClass()
} else {
instance = SomethingElseClass()
}
}
func doSomething() {
instance.doSomething()
}
}
class SomeOtherClass: SomeProtocol {
func doSomething() {
print("something")
}
}
class SomethingElseClass: SomeProtocol {
func doSomething() {
print("something else")
}
}
Basically you create a protocol that your class cluster inherits from. You then wrap around an instance variable of the same type and choose which implementation to use.
For example, if you were writing an array class that switched between a LinkedList or a raw array then SomeOtherClass and SomethingElseClass might be named LinkedListImplementation or PlainArrayImplementation and you could decide which one to instantiate or switch to based on whatever is more efficient.
There is a way to achieve this. Whether it is good or bad practice is for another discussion.
I have personally used it to allow for extension of a component in plugins without exposing the rest of the code to knowledge of the extensions. This follows the aims of the Factory and AbstractFactory patterns in decoupling code from the details of instantiation and concrete implementation classes.
In the example case the switching is done on a typed constant to which you would add in extensions. This kinda contradicts the above aims a little technically - although not in terms of foreknowledge. But in your case the switch might be anything - the number of wheels for example.
I don’t remember if this approach was available in 2014 - but it is now.
import Foundation
struct InterfaceType {
let impl: Interface.Type
}
class Interface {
let someAttribute: String
convenience init(_ attribute: String, type: InterfaceType = .concrete) {
self.init(impl: type.impl, attribute: attribute)
}
// need to disambiguate here so you aren't calling the above in a loop
init(attribute: String) {
someAttribute = attribute
}
func someMethod() {}
}
protocol _Factory {}
extension Interface: _Factory {}
fileprivate extension _Factory {
// Protocol extension initializer - has the ability to assign to self, unlike class initializers.
init(impl: Interface.Type, attribute: String) {
self = impl.init(attribute: attribute) as! Self;
}
}
Then in a concrete implementation file ...
import Foundation
class Concrete: Interface {
override func someMethod() {
// concrete version of some method
}
}
extension InterfaceType {
static let concrete = InterfaceType(impl: Concrete.self)
}
For this example Concrete is the "factory" supplied default implementation.
I have used this, for example, to abstract the details of how modal dialogs were presented in an app where initially UIAlertController was being used and migrated to a custom presentation. None of the call sites needed changing.
Here is a simplified version that does not determine the implementation class at runtime. You can paste the following into a Playground to verify its operation ...
import Foundation
class Interface {
required init() {}
convenience init(_ discriminator: Int) {
let impl: Interface.Type
switch discriminator {
case 3:
impl = Concrete3.self
case 2:
impl = Concrete2.self
default:
impl = Concrete1.self
}
self.init(impl: impl)
}
func someMethod() {
print(NSStringFromClass(Self.self))
}
}
protocol _Factory {}
extension Interface: _Factory {}
fileprivate extension _Factory {
// Protocol extension initializer - has the ability to assign to self, unlike class initializers.
init(impl: Interface.Type) {
self = impl.init() as! Self;
}
}
class Concrete1: Interface {}
class Concrete2: Interface {}
class Concrete3: Interface {
override func someMethod() {
print("I do what I want")
}
}
Interface(2).someMethod()
Interface(1).someMethod()
Interface(3).someMethod()
Interface(0).someMethod()
Note that Interface must actually be a class - you can't collapse this down to a protocol avoiding the abstract class even if it had no need for member storage. This is because you cant invoke init on a protocol metatype and static member functions cannot be invoked on protocol metatypes. This is too bad as that solution would look a lot cleaner.
We can take advantage of a compiler quirk - self is allowed to be assigned in protocol extensions - https://forums.swift.org/t/assigning-to-self-in-protocol-extensions/4942.
Thus, we can have in place something like this:
/// The sole purpose of this protocol is to allow reassigning `self`
fileprivate protocol ClusterClassProtocol { }
extension ClusterClassProtocol {
init(reassigningSelfTo other: Self) {
self = other
}
}
/// This is the base class, the one that gets circulated in the public space
class ClusterClass: ClusterClassProtocol {
convenience init(_ intVal: Int) {
self.init(reassigningSelfTo: IntChild(intVal))
}
convenience init(_ stringVal: String) {
self.init(reassigningSelfTo: StringChild(stringVal))
}
}
/// Some private subclass part of the same cluster
fileprivate class IntChild: ClusterClass {
init(_ intVal: Int) { }
}
/// Another private subclass, part of the same cluster
fileprivate class StringChild: ClusterClass {
init(_ stringVal: String) { }
}
Now, let's give this a try:
print(ClusterClass(10)) // IntChild
print(ClusterClass("abc")) // StringChild
This works the same as in Objective-C, where some classes (e.g. NSString, NSArray, NSDictionary) return different subclasses based on the values given at initialization time.