[ios] Xcode 8 / Swift 3 :“UIViewController 유형의 표현? 사용되지 않습니다”경고

이전에 깨끗하게 컴파일되었지만 Xcode 8로 경고를 생성하는 다음 함수가 있습니다.

func exitViewController()
{
    navigationController?.popViewController(animated: true)
}

“”UIViewController? “유형의 표현은 사용되지 않습니다.”

왜 이것이 말하고 그것을 제거하는 방법이 있습니까?

코드가 예상대로 실행됩니다.



답변

TL; DR

popViewController(animated:)반환 UIViewController?하고 컴파일러는 값을 캡처하지 않기 때문에 경고를 표시합니다. 해결책은 밑줄에 지정하는 것입니다.

_ = navigationController?.popViewController(animated: true)

스위프트 3 변경

Swift 3 이전에는 모든 메소드에 기본적으로 “삭제 가능한 결과”가있었습니다. 메소드가 리턴 한 내용을 캡처하지 않으면 경고가 발생하지 않습니다.

결과를 캡처해야한다고 컴파일러에 알리 @warn_unused_result려면 메서드 선언 전에 추가 해야했습니다. 변경 가능한 형식 (예 : sortsortInPlace) 을 가진 메소드에 사용됩니다 . @warn_unused_result(mutable_variant="mutableMethodHere")컴파일러에게 알려주기 위해 추가 할 것입니다.

그러나 Swift 3에서는 동작이 뒤집 힙니다. 모든 메소드는 이제 리턴 값이 캡처되지 않음을 경고합니다. 컴파일러에 경고가 필요하지 않다고 알리려면 다음을 추가하십시오.@discardableResult 메소드 선언 전에 .

반환 값을 사용하지 않으려면 밑줄에 할당 하여 명시 적으로 컴파일러에 알려야합니다.

_ = someMethodThatReturnsSomething()

이것을 스위프트 3에 추가 한 동기 :

  • 가능한 버그 방지 (예 : sort 컬렉션을 수정한다고 생각하는 경우)
  • 다른 공동 작업자의 결과를 캡처하지 않거나 캡처 할 필요가있는 명백한 의도

UIKit API는 이것보다 뒤에있는 것으로 보이며 반환 값을 캡처하지 않고 @discardableResult완벽하게 정상적인 (더 일반적이지는 않지만) 사용을 추가하지 않습니다 popViewController(animated:).

더 읽어보기


답변

인생이 당신에게 레몬을 줄 때, 확장을하십시오 :

import UIKit

extension UINavigationController {
    func pop(animated: Bool) {
        _ = self.popViewController(animated: animated)
    }

    func popToRoot(animated: Bool) {
        _ = self.popToRootViewController(animated: animated)
    }
}

다음과 같은 것을 추가 하십시오.@discardableResult func pop(animated: Bool) -> UIViewController? 당신이 피하려고하는 것과 같은 경고가 발생합니다.

확장 기능을 사용하면 다음과 같이 작성할 수 있습니다.

func exitViewController()
{
    navigationController?.pop(animated: true)
}

func popToTheRootOfNav() {
    navigationController?.popToRoot(animated: true)
}

편집 : popToRoot도 추가되었습니다.


답변

Swift 3에서 선언 된 리턴 값이있는 함수의 리턴 값을 무시하면 경고가 발생합니다.

이것을 거부하는 한 가지 방법은 함수로 @discardableResult속성 을 표시하는 것입니다 . 이 기능을 제어 할 수 없으므로 작동하지 않습니다.

경고를 제거하는 다른 방법은 값을에 할당하는 것 _입니다. 이것은 컴파일러에게 메소드가 값을 리턴한다는 것을 알고 있지만 메모리에 유지하고 싶지 않다는 것을 알려줍니다.

let _ = navigationController?.popViewController(animated: true)


답변

스크린 샷 1

비록 work correctly if kept as it is 하지만,number of warning increases.

해결책은 단순히 replace it with underscore ( _ )추한 것 같습니다.

Eg.  _ = navigationController?.popViewController(animated: true)

스크린 샷 2


답변

이 조건에서 폐기 가능한 결과 를 사용하십시오 .

<Swift Programming Language>에 따르면 언어 참조-속성 장을 참조하십시오.

폐기 가능 결과

값을 리턴하는 함수 또는 메소드가 결과를 사용하지 않고 호출 될 때 컴파일러 경고를 억제하려면이 속성을 함수 또는 메소드 선언에 적용하십시오.

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Attributes.html#//apple_ref/doc/uid/TP40014097-CH35-ID347

<Swift Programming Language>, Language Guide-Methods 장에 데모가 있습니다.

@discardableResult
    mutating func advance(to level: Int) -> Bool {
    ...
return true
}

advance (to 🙂 메소드를 호출하여 리턴 값을 무시하는 코드가 반드시 실수는 아니기 때문에이 함수는 @discardableResult 속성으로 표시됩니다. 이 속성에 대한 자세한 내용은 속성을 참조하십시오.

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html#//apple_ref/doc/uid/TP40014097-CH15-ID234


답변

CodeReaper의 답변과 같은 확장의 길을 가고 싶다면을 사용해야합니다 @descardableResult. 이렇게하면 모든 가능성이 유지되지만 경고는 사라집니다.

import UIKit

extension UINavigationController {
    @discardableResult func pop(animated: Bool) -> UIViewController? {
        return self.popViewController(animated: animated)
    }

    @discardableResult func popToRoot(animated: Bool) -> [UIViewController]? {
        return self.popToRootViewController(animated: animated)
    }
}


답변

다른 방법은 self.navigationController?값을 풀고 popViewController함수를 호출하는 것입니다.

    if let navigationController = navigationController {
        navigationController.popViewController(animated: true)
    }