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


230

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

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

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

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

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

답변:


498

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:).

더 읽어보기


15
이것은 그들이 비록 그,이 같은 방법이 있습니다, 특히 확실히 (내 생각에) 스위프트 2에서 단계 돌아 값을 반환, 당신은 단지 그것을 사용하지 않는 완벽하게 유효한 사용 사례가있다.
Nicolas Miari 2016 년

15
1. 필요하지 않습니다 let: let또는 앞에 _를 붙이지 않고 _에 지정할 수 있습니다 var.
rickster 2018 년

1
@rickster 답을 추가 할 줄 몰랐습니다.
tktsubota 2016 년

5
2. @NicolasMiari 버그를 제출하십시오 . @discardableResult값을 반환하지만 반환 값을 무시할 것으로 예상되는 함수 에는 주석 ( )이 있습니다. UIKit은 API에 해당 주석을 적용하지 않았습니다.
rickster 2018 년

37
이것은 끔찍한 구문입니다. 그들은 왜 이것을 할 것입니까? 왝.
David S.

38

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

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도 추가되었습니다.


Xcode 업데이트에서 수정해야 할 사항에 대한 가장 확실한 수정이므로 허용되는 솔루션이어야합니다.
Philip Broadway

24

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

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

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

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

2
_애플이이 새로운 속성으로 UIKit을 업데이트 할 때까지 추악한 것을 고수해야한다고 생각 합니다.
Nicolas Miari 2016 년

2
불행히도 @discardableResult작동하지 않습니다 (적어도 여전히 8b4에서는 삐걱 거리지 않습니다). Friedrich Schiller는 썩은 사과를 좋아했습니다. 아마 맛의 문제 :-(
qwerty_so

5

스크린 샷 1

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

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

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

스크린 샷 2


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


0

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

-1

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

    if let navigationController = navigationController {
        navigationController.popViewController(animated: true)
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.