2017-03-08 8 views
0

저는 클로저를 매개 변수로 취하고 클래스의 인스턴스를 만들고 클로저를 전달하는 제네릭 클래스에 정적 메서드를 만들려고합니다. 캐치 (catch)는이 클래스를 서브 클래스 화하고 클로저가 내가 사용하는 모든 서브 클래스를 준수하는지 확인하고자한다.Swift 3 : 클로저 유형을 Self로 제한하기 위해 정적 클래스 함수를 선언하는 방법은 없나요?

난 당신이 정적 메서드에 대한 반환 형식으로 "자기"를 사용할 수 있다는 것을 알고,하지만 난 방법 헤더에 사용하려고하면, 나는 다음과 같은 오류 얻을 :

"'Self' is only available in a protocol or as the result of a method in a class"

내가 좋겠를 이런 식으로 뭔가를 좋아 : 다른

class GenericClass: NSObject { 
    required override init() { 
     super.init() 
    } 

    static func createAndExecuteAsync(block: (Self) -> Void) { 
     DispatchQueue.global().async { 
      let instance = self.init() 
      block(instance) 
     } 
    } 
} 

class OtherClass: GenericClass { 
    // ... 
} 

어딘가에 ...

OtherClass.createAndExecuteAsync { (instance: OtherClass) in 
    // Do stuff to instance 
} 

UPDATE :

Hamish의 해결책 덕분에 this post에 가깝습니다. 저는 해결책에 더 가깝습니다. 내가 제네릭 클래스의 프로토콜을 처음 만들면 원하는 방식으로 Self를 사용할 수 있습니다. 그러나 그것은 내가 내게는 바람직하지 않은 OtherClass를 최종 결정하게 만든다.

protocol GenericClass { 
    init() 
    static func createAndExecuteAsync(block: @escaping (Self) -> Void) 
} 

extension GenericClass { 
    static func createAndExecuteAsync(block: @escaping (Self) -> Void) { 
     DispatchQueue.global().async { 
      let instance = self.init() 
      block(instance) 
     } 
    } 
} 

final class OtherClass : GenericClass { 
    var myProperty = 1 

    required init() { } 
} 

// Somewhere else... 
OtherClass.createAndExecuteAsync { (instance) in 
    instance.myProperty = 2 
} 
+0

전적으로 관련 (속는?) : INIT PARAMS자가 (http://stackoverflow.com/q/40055862/2976878). [내 대답] (http://stackoverflow.com/a/42356615/2976878)에 나와있는 것처럼 프로토콜을 사용하고 해당 프로토콜의 확장에'createAndExecuteAsync' 메서드를 넣을 수 있습니다. 그러나 궁극적으로 이것이 프로토콜 확장을 벗어나서는 안될 이유가 없습니다. – Hamish

+0

@Hamish 저 게시물에서 저에게 해결책을 알려 주셔서 감사합니다. 그게 내가 이상적인 클래스가 아닌 최종 클래스를 사용하게 만들지 만, 솔루션에 훨씬 더 가까워진다. – Mel

+0

아, 그렇습니다. 답안에서 언급 한 거친 부분입니다. 프로토콜 요구 사항에서'createAndExecuteAsync'를 제거해야하며 확장에서만 가져야합니다. 그렇게하면 코드가 비 최종 클래스로 컴파일 될 수 있습니다. :) – Hamish

답변

0

는 아마도 약간 다른 사용 구문 글로벌 일반적인 기능을 사용할 수 있습니다 여기에

Protocol 'GenericClass' requirement 'createAndExecuteAsync(block:)' cannot be satisfied by a non-final class ('OtherClass') because it uses 'Self' in a non-parameter, non-result type position.

것처럼 보일 것 기능 :

OtherClass의 마지막을하지 않고, 나는 다음과 같은 오류가 발생합니다 . 예

:

func createAndExecuteAsync<T:GenericClass>(_ objectType:T.Type, _ block:@escaping (T) -> Void) 
{ 
    DispatchQueue.global().async 
    { 
     let instance = T.init() 
     block(instance) 
    } 
} 


createAndExecuteAsync(OtherClass.self){ $0.myProperty = 2 } 

// instead of OtherClass.createAndExecuteAsync{ $0.myProperty = 2 }