Xcode 8 / स्विफ्ट 3: "UIViewController के प्रकार की अभिव्यक्ति? अप्रयुक्त है ”चेतावनी


230

मुझे निम्न फ़ंक्शन मिला है जो पहले साफ-सुथरा संकलित करता है लेकिन Xcode 8 के साथ चेतावनी देता है।

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

"प्रकार की अभिव्यक्ति" UIViewController? "अप्रयुक्त है"।

यह ऐसा क्यों कह रहा है और क्या इसे हटाने का कोई तरीका है?

कोड अपेक्षित रूप से निष्पादित होता है।

जवाबों:


498

टी एल; डॉ

popViewController(animated:)रिटर्न UIViewController?, और कंपाइलर उस चेतावनी को दे रहा है क्योंकि आप मूल्य पर कब्जा नहीं कर रहे हैं। समाधान यह है कि इसे अंडरस्कोर में सौंपा जाए:

_ = navigationController?.popViewController(animated: true)

स्विफ्ट 3 बदलें

स्विफ्ट 3 से पहले, सभी तरीकों में डिफ़ॉल्ट रूप से "त्यागने योग्य परिणाम" था। जब आपने विधि वापस नहीं ली तो कोई चेतावनी नहीं होगी।

संकलक को यह बताने के लिए कि परिणाम पर कब्जा किया जाना चाहिए, आपको @warn_unused_resultविधि घोषणा से पहले जोड़ना होगा । यह तरीकों एक परिवर्तनशील रूप (उदा। होती हैं, के इस्तेमाल किया जाएगा sortऔर sortInPlace)। आप इसके @warn_unused_result(mutable_variant="mutableMethodHere")संकलक को बताना चाहेंगे ।

हालाँकि, स्विफ्ट 3 के साथ, व्यवहार फ़्लिप है। सभी तरीकों ने अब चेतावनी दी है कि वापसी मूल्य पर कब्जा नहीं किया गया है। यदि आप संकलक को बताना चाहते हैं कि चेतावनी आवश्यक नहीं है, तो आप @discardableResultविधि घोषणा से पहले जोड़ते हैं ।

यदि आप रिटर्न मान का उपयोग नहीं करना चाहते हैं, तो आपको इसे अंडरस्कोर पर असाइन करके कंपाइलर को स्पष्ट रूप से बताना होगा:

_ = someMethodThatReturnsSomething()

इसे स्विफ्ट 3 में जोड़ने के लिए प्रेरणा:

  • संभावित बगों की रोकथाम (पूर्व sortसोच का उपयोग करके यह संग्रह को संशोधित करता है)
  • अन्य सहयोगियों के लिए परिणाम पर कब्जा करने या न करने की स्पष्ट मंशा

UIKit एपीआई इस पर पीछे दिखाई देता है, रिटर्न वैल्यू को कैप्चर किए बिना @discardableResultपूरी तरह से सामान्य (यदि अधिक सामान्य नहीं) उपयोग के लिए जोड़ रहा है popViewController(animated:)

अधिक पढ़ें


15
यह (मेरी राय में) निश्चित रूप से स्विफ्ट 2 से एक कदम पीछे है, खासकर जब इस तरह के तरीके हैं, भले ही वे एक मूल्य वापस करते हैं, वहाँ पूरी तरह से वैध उपयोग के मामले हैं जहां आप इसका उपयोग नहीं करते हैं।
निकोलस मिआरी

15
1. आपको इसकी आवश्यकता नहीं है let: आप इसे पहले letया इसके बिना _ को असाइन कर सकते हैं var
रिकस्टर

1
@rickster पता नहीं था कि जवाब देने के लिए जोड़ देगा।
tktsubota

5
2. @ निलामोसारी एक बग फाइल करें । ऐसे @discardableResultकार्यों के लिए एक एनोटेशन ( ) है जो एक मान लौटाते हैं, लेकिन जहां यह उम्मीद की जाती है कि कोई वापसी मूल्य की अनदेखी कर सकता है। UIKit ने केवल उस एनोटेशन को उनके API पर लागू नहीं किया है।
रिकस्टर

37
यह भयानक वाक्यविन्यास है। वे ऐसा क्यों करेंगे? छी।
डेविड एस।

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 अपडेट में निश्चित होना निश्चित है।
फिलिप ब्रॉडवे

24

स्विफ्ट 3 में, एक फ़ंक्शन के रिटर्न मूल्य को अनदेखा करना, जिसमें एक चेतावनी में घोषित वापसी मूल्य परिणाम होता है।

इससे बाहर निकलने का एक तरीका @discardableResultविशेषता के साथ फ़ंक्शन को चिह्नित करना है । चूंकि आपके पास इस फ़ंक्शन पर नियंत्रण नहीं है, इसलिए यह काम नहीं करेगा।

चेतावनी से छुटकारा पाने का दूसरा तरीका मूल्य को असाइन करना है _। यह संकलक को बताता है कि आप जानते हैं कि विधि एक मान लौटाती है लेकिन आप इसे स्मृति में नहीं रखना चाहते हैं।

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

2
मुझे लगता है कि _जब तक Apple UIKit को इस नई विशेषता के साथ अपडेट नहीं करता, तब तक हमें बदसूरत के साथ रहना होगा ।
निकोलस मिआरी

2
दुर्भाग्य से @discardableResultकाम नहीं करता है (कम से कम यह अभी भी 8b4 के साथ क्रोक्स करता है)। फ्रेडरिक शिलर को सड़े हुए सेब बहुत पसंद थे। शायद स्वाद की बात:
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

इस हालत में त्यागने योग्यResult का प्रयोग करें ।

<स्विफ्ट प्रोग्रामिंग भाषा> के अनुसार, अध्याय भाषा संदर्भ - विशेषताएँ।

discardableResult

फ़ंक्शन या पद्धति को दबाने वाले संकलक को दबाने के लिए इस विशेषता को एक फ़ंक्शन या विधि घोषणा पर लागू करें जब कोई मान लौटाता है, जो उसके परिणाम का उपयोग किए बिना कहा जाता है।

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

<Swift प्रोग्रामिंग लैंग्वेज>, चैप्टर लैंग्वेज गाइड - मेथड्स में भी एक डेमो है।

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

क्योंकि यह जरूरी नहीं है कि कोड के लिए कोई गलती हो जो अग्रिम (:) तरीके से रिटर्न वैल्यू को नजरअंदाज करे, यह फ़ंक्शन @discardableResult विशेषता के साथ चिह्नित है। इस विशेषता के बारे में अधिक जानकारी के लिए, विशेषताएँ देखें।

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


0

यदि आप एक्सटेंशन की सड़क पर जाना चाहते हैं जैसे कि कोडरॉइस का जवाब जो आपको उपयोग करना चाहिए @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)
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.