एक घोषणा स्विफ्ट 1.2 में 'अंतिम' और 'गतिशील' दोनों त्रुटि नहीं हो सकती है


123

valueनीचे की घोषणा

import Foundation

class AAA: NSObject {
    func test2() {
        self.dynamicType
    }
}
extension AAA {
    static let value    =   111
}

निम्नलिखित संकलन त्रुटि का कारण बनता है

A declaration cannot be both 'final' and 'dynamic'

ऐसा क्यों होता है, और मैं इससे कैसे निपट सकता हूं?

मैं स्विफ्ट 1.2 (Xcode 6.3.1 6D1002 के भीतर शिप किया गया संस्करण) का उपयोग कर रहा हूं


func test2घोषणा Xcode 7.3.1 के रूप में, त्रुटि को गति प्रदान करने की जरूरत नहीं है।
लूट सकते हैं


बस उस स्थिर चर को एक और बेहतर नामकरण संरचना में रखें
onmyway133

जवाबों:


224

यह समस्या इसलिए पैदा होती है क्योंकि स्विफ्ट ओब्ज-सी अनुकूलता के लिए स्थैतिक संपत्ति के लिए एक गतिशील सहायक उत्पन्न करने की कोशिश कर रहा है, क्योंकि कक्षा से विरासत में मिली है NSObject

यदि आपकी परियोजना केवल स्विफ्ट में है, तो एक varएक्सेसर का उपयोग करने के बजाय आप @nonobjcस्विफ्ट 2.0 में विशेषता के माध्यम से समस्या से बच सकते हैं :

import Foundation

class AAA: NSObject {}
extension AAA {
    @nonobjc static let value = 111
}

मेरी परियोजना में कुछ ऑब्जेक्टिव-सी फाइलें हैं, लेकिन उनमें से कोई भी कोड इस वर्ग ( AAAयहां) के उदाहरणों के साथ बातचीत नहीं करता है , इसलिए मुझे लगता है कि मैं स्पष्ट हूं?
निकोलस मिआरी

शुद्ध स्विफ्ट कोडबेस का उपयोग करते समय यह चयनित उत्तर होना चाहिए।
इडस्की

मैं एक NSManagedObjectउपवर्ग में स्थिर (वर्ग) संस्करण जोड़ने की कोशिश कर रहा था । यह तय!
निकोलस मिआरी

क्या मैं अकेला हूँ जिसने इस फिक्स को Xcode 7.3 के लिए SourceKitService को पूरी तरह से खराब करने के लिए पाया है?
NoodleOfDeath

57

यदि आपकी कक्षा इन शर्तों को पूरा करती है तो आपको यह त्रुटि मिलेगी।

  • से उपकृत किया गया NSObject
  • एक static letमैदान है।
  • किसी इंस्टेंस विधि से फ़ील्ड को एक्सेस करता है dynamicType

मुझे नहीं पता कि ऐसा क्यों होता है, लेकिन आप इस समाधान की कोशिश कर सकते हैं।

static var value: Int {
    get {
        return 111
    }
}

या छोटे रूप में।

static var value: Int {
    return 111
}

के static var { get }बजाय का उपयोग करें static let


हालाँकि उपरोक्त उदाहरण में एलएलवीएम ऑप्टिमाइज़र द्वारा संपत्ति पाने वाले और इसकी कॉलिंग लागत को समाप्त करने की संभावना है, आप स्पष्ट रूप से इससे बचना चाहते हैं।

यदि आप ऐसी मूल्य गणना लागत के बारे में चिंतित हैं, तो आप इसे एक बार बना सकते हैं और इस तरह से कैश कर सकते हैं।

static var value: Int {
    return cache
}
private let cache = getTheNumber()

या इस तरह अगर आप कैश के अस्तित्व को पूरी तरह छिपाना चाहते हैं।

static var value: Int {
    struct Local {
        static let cache = getTheNumber()
    }
    return Local.cache
}

5
यह एक गणना की गई संपत्ति का उत्पादन करता है, जिसे हर पहुंच में फिर से जोड़ा जाएगा। इस मामले के लिए यह बहुत ज्यादा मायने नहीं रखता है, लेकिन मुझे लगता है कि यह ध्यान देने योग्य है, ताकि कोई भी बड़ी वस्तुओं के लिए इस समाधान का उपयोग न करे।
निक पॉड्रैटज़

@NickPodratz क्या यह एक परिकलित संपत्ति होगी? private static let _value: Int = 111 static var value: Int { return _value }यह नहीं है, get {लेकिन संकलक संपत्ति के बारे में कुछ का उल्लेख करता है अगर मैं varइसके बजाय का उपयोग करता हूंlet
हैशियर

1
@ शशियर यह है। घुंघराले ब्रेसिज़ के अंदर आप एक क्लोजर बनाते हैं, getइस मामले में निहित है। इसके बजाय आप क्या कर सकते हैं, चर को बंद करने के परिणाम को असाइन करें ताकि बंद को सिर्फ एक बार कहा जाए let value: Int = { return 111 }():। अंत में कोष्ठक बंद को बुलाते हैं। लेकिन ध्यान रखें कि यह फिर से एक संग्रहीत संपत्ति है और इसलिए एक्सटेंशन में उपलब्ध नहीं है।
निक पॉड्रैटज़

@NickPodratz के आकलन से सहमत हैं। हालांकि यह ओपी उल्लेख की त्रुटि को हल करता है और इसलिए यह एक कानूनी जवाब बनाता है, यह कोई लाभ नहीं देता है यदि आप अपने चर को वास्तव में स्थिर होना चाहते हैं (जो बिंदु की तरह लगता है)। एलेक्स का जवाब उस मामले में बेहतर है (शुद्ध स्विफ्ट मानकर)
मैट लॉन्ग

18

मेरी भी यही त्रुटि थी।

मेरा मुद्दा एक तेजी से विस्तार में सिर्फ एक स्थिर संस्करण था ।

extension NotificationsViewController: UITableViewDataSource , UITableViewDelegate {

    static var timeIntervalFormatter = NSDateComponentsFormatter()

}

इसे कक्षा में लागू करने से मेरे लिए समस्या का समाधान हो गया।


7

मैं बस एक ही मुद्दे पर एक अलग कारण के साथ ठोकर खाई और अन्य लोगों के लिए एक ही बेकार त्रुटि संदेश का अनुभव करने के लिए इसे यहाँ पोस्ट करना चाहूंगा।

एक अंतिम वर्ग जो एक विस्तार में परिभाषित कम्प्यूटेड चर को ओवरराइड करता है, इस त्रुटि का कारण भी बनता है। यह फ़ंक्शंस के लिए काम करता है और इस तरह एक कंपाइलर बग की तरह दिखता है।

// at line 0: a declaration cannot be both 'final' and 'dynamic'

import UIKit

extension UIViewController {
    var test: Int { return 0 }
}

final class TestController: UIViewController {
    override var test: Int { return 1 }
}

7

एक्सटेंशन में परिभाषित नई संरचना में स्थिर घोषणा को स्थानांतरित करके मैंने इस मुद्दे को हल किया।

इसलिए इसके बजाय:

extension NSOperationQueue {
    static var parsingQueue : NSOperationQueue = {
        let queue = NSOperationQueue()
        queue.maxConcurrentOperationCount = 1
        return queue
        }()
}

मेरे पास यह है:

extension NSOperationQueue {        
    struct Shared {
        static var parsingQueue : NSOperationQueue = {
            let queue = NSOperationQueue()
            queue.maxConcurrentOperationCount = 1
            return queue                
            }()
    }
}

0

इस त्रुटि को रोकने के लिए आप इसे निजी के रूप में चिह्नित कर सकते हैं। यदि आप इसे उजागर करना चाहते हैं, तो आप इसे एक सार्वजनिक समारोह में लपेट सकते हैं:

extension AAA {

    private static let value = 111

    public func getDatValue() -> Int {
        return AAA.value
    }    
}

मेरे मामले में, मैंने केवल एक्सटेंशन में ही संपत्ति का उल्लेख किया था, इसलिए इसे उजागर करने की कोई आवश्यकता नहीं थी।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.