문제

이것은 상대적으로 일반적인 디자인 패턴:

https://stackoverflow.com/a/17015041/743957

그것은 당신을 반환 서브 클래스에서 당신의 init 호출합니다.

하려고 해요 최고의 방법을 달성하기 같은 것을 사용하여 신속합니다.

내가 알고있는것은 매우 가능성이 있다는 것을 더 나은 방법을 달성하기 같은 것으로 신속합니다.그러나 내가에 의해 초기화될 기존 Obj-C 라이브러리는 나는 없다.그래서 그것은 필요가 이러한 방식으로 작동하고 호출할 수 있어서 Obj-C.

어떤 포인터는 것이 매우 감사합니다.

도움이 되었습니까?

해결책

나는 그것을 믿지 않는 이유한 패턴을 가지고 있다는 사실 직접 지원에 신속하기 때문에,initialisers 값을 반환하지 않습으로 그들은 목 C-하지 않도록 할 수있는 기회를 얻을 반환하는 다른 객체를 인스턴스입니다.

형식을 사용할 수 있습 방법 개체로 공장이 상당히 인위적인 예입니다-

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
       }
     }
}

습니다.스

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

다른 팁

는"구라"의 방법을 만들기 클래스는 클러스터에는 실제로 이러한 프로토콜 대신의 기본 클래스입니다.

분명히 컴파일러에서 금지하는 정적 기능에 프로토콜 또는 프로토콜을 확장자.

까지 예: https://github.com/apple/swift-evolution/pull/247 (공장의 이니셜라이저)받아들이 구현,유일한 방법은 찾을 수 있는 이렇게 하려면 다음과 같다:

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)

init() 지 않는 반환 값 -init 는 목 C 를 사용하여,공장 방법은 다음과 같 가장 쉬운 방법입니다.

하나의 트릭을 표시하는 것입니다 당신의 이니셜라이저로 private, 은 다음과 같습니다.

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!"
        }
    }
}

이 결과는 다음과 같은 문제가 발생합니다.

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

그것은 아주 좋은 목적이 C 이후 private 수단,모든 서브 클래스에서 구현되어야 합 같이 소스 파일이 있는 사소한 차이는 구문 Person.person(x) (나 Person.create(x) 또 무엇이든)신의 단순히 Person(x), 지만,실제적으로 말하면,그것은 동일합니다.

할 수 있을 그대로를 인스턴스화 Person(x), 수 차례 Person 으로는 프록시 등을 포함하는 개인스턴스의 실제 기본 클래스고 앞으로 모든 것을니다.없이 메시지 전달,이 작품에 대한 간단한 인터페이스와 함께 몇 가지 특성/법만 다루기 위해 더 복잡:P

내가 생각하는 실제로 클러스터의 패턴을 구현할 수 있습에서 신속을 사용하여 런타임 기능이 있다.주요 포인트이 대체하는 등의 새로운 객체와 함께 하위 클래스 경우를 초기화하고 있습니다.아래의 코드를 작동 하지만 나는 생각이 더 많은 관심 지불해야 하위 클래스'초기 설정입니다.

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)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top