Programing

클로저를 Swift 3로 업데이트-@escaping

lottogame 2020. 10. 20. 07:11
반응형

클로저를 Swift 3로 업데이트-@escaping


내 코드를 Xcode 8.0 베타 6으로 업데이트했지만 새로운 비 이스케이프 클로저 기본값에 대한 것 같은 문제가 발생했습니다. 다음 코드에서 Xcode는 아래 코드의 첫 번째 줄 @escaping앞에 추가 할 것을 제안 completion:하지만 여전히 컴파일되지 않고 원으로 이동합니다. *

( 편집 : 사실, @escaping은 Xcode가 제안한대로 뒤에 추가해야합니다 completion:. 경고는 여전히 표시 될 수 있지만 정리 및 컴파일하면 제거됩니다.) * 업데이트 된 Swift 3에서 작동하도록이 코드를 어떻게 다시 작성 / 수정해야합니까? ? 새 매뉴얼을 살펴 봤지만 적절한 코드 샘플을 찾을 수 없었습니다.

func doSomething(withParameter parameter: Int, completion: () -> ()) {
    // Does something

    callSomeOtherFunc(withCompletion: completion)
  }

// Calling the method and execute closure 
doSomething(withParameter: 2) {
  // do things in closure
}

많은 도움을 주셔서 감사합니다!


Swift 3 : 클로저 매개 변수 속성이 이제 매개 변수 자체가 아닌 매개 변수 유형에 적용 됩니다.

Swift 3 이전에는 클로저 속성 @autoclosure@noescape클로저 매개 변수의 속성 이었지만 이제는 매개 변수 유형의 속성입니다 . 다음 수락 된 Swift 진화 제안을 참조하십시오.

귀하의 특정 질문은 @escaping(동일한 새 규칙이 적용되는) 매개 변수 유형 속성과 관련이 있습니다. 이는 허용 된 Swift 진화 제안에서 기본적으로 클로저 매개 변수가 이스케이프되지 않도록 허용합니다.

이러한 제안은 이제 Xcode 8의 베타 단계에서 구현됩니다 ( Xcode 8 베타 6의 릴리스 노트 참조 , 액세스하려면 개발자 계정 로그인 필요).

Xcode 8 베타 6의 새로운 기능-Swift Compiler : Swift Language

클로저 매개 변수는 명시 적으로 주석이 추가되지 않고 기본적으로 이스케이프되지 않습니다 @noescape. @escaping클로저 매개 변수가 이스케이프 될 수 있음을 나타내는 데 사용 합니다. @autoclosure(escaping)이제 @autoclosure @escaping. @noescape주석은 @autoclosure(escaping)더 이상 사용되지 않습니다. (SE-0103)

...

Xcode 8 베타의 새로운 기능 – Swift 및 Apple LLVM 컴파일러 : Swift 언어

이제 @noescape@autoclosure속성은 매개 변수 이름이 아닌 매개 변수 유형 앞에 작성되어야합니다. [SE-0049]

따라서 @escaping다음과 같이 기본이 아닌 속성을 사용합니다. 매개 변수 자체가 아닌 클로저 매개 변수 유형적용됩니다.

func doSomething(withParameter parameter: Int, completion: @escaping () -> ()) {
    // ...
}

(댓글은 SO에 대한 지속적인 데이터가 아니기 때문에 아래의 찬성 댓글에 질문에 대한 답변 포함)

@Cristi Băluță : "이스케이프는 무엇을합니까? swift3 자동 변환 전에이 키워드를 본 적이 없습니다 ..."

예를 들어 SE-0103 진화 제안에 대한 링크 (베타 6 릴리스 노트에서 인용 된 텍스트 포함)를 참조하십시오. 이전에는 클로저 매개 변수가 기본적으로 이스케이프되었습니다 (따라서 이스케이프를위한 명시 적 주석이 필요하지 않음). 그러나 이제는 기본적으로 이스케이프되지 않습니다. 따라서를 추가 @escaping하면 클로저 매개 변수가 이스케이프 될 수 있음을 명시 적으로 주석 처리 할 수 ​​있습니다 (기본 동작과 달리). 이것은 또한 @noescape현재 사용되지 않는 이유를 설명합니다 (기본 동작에 주석을 달 필요가 없음).

클로저 매개 변수가 이스케이프된다는 의미를 설명하기 위해 언어 참조-속성을 인용 합니다 .

"이 속성을 메서드 또는 함수 선언의 매개 변수 유형에 적용하여 나중에 실행하기 위해 매개 변수 값을 저장할 수 있음을 나타냅니다. 이는 해당 값이 호출 수명보다 오래 지속될 수 있음을 의미합니다."


@noescape

xcode 8에서 베타 6 @noescape이 기본값입니다. 그 전에는 @escaping기본값이었습니다. 이전 버전에서 swift 3.0으로 업데이트하는 사람은 누구나이 오류에 직면 할 수 있습니다.

@noescape변수 안에 클로저를 저장할 수 없습니다 . 변수 안에 클로저를 저장할 수 있다면 코드의 어느 곳에서나 클로저를 실행할 수 있기 때문입니다. 그러나 @noescape클로저 매개 변수는 함수의 본문을 벗어날 수 없음을 나타냅니다.

Xcode 8에서 컴파일러 오류가 발생합니다.

class MyClass {

    var myClosure: (() -> ())?

    func doSomething(finishBlock: () -> ()) {
        myClosure = finishBlock    // ‼️ Error: Assigning non-escaping parameter 'finishBlock' to an @escaping closure
    }
}

이것은 정상적으로 컴파일됩니다 (명시 적으로 작성 @escaping)

class MyClass {

    var myClosure: (() -> ())?

    func doSomething(finishBlock: @escaping () -> ()) {
        myClosure = finishBlock
    }
}

혜택 @noescape:

  • Compiler can optimize your code for better Performance
  • Compiler can take care of memory management
  • There is no need to use a weak reference to self in the closure


For details check out: Make non-escaping closures the default

참고URL : https://stackoverflow.com/questions/39063499/updating-closures-to-swift-3-escaping

반응형