कमजोर लिंकिंग - जांचें कि क्या कोई वर्ग मौजूद है और उस वर्ग का उपयोग करें


87

मैं एक सार्वभौमिक आईफ़ोन ऐप बनाने की कोशिश कर रहा हूं, लेकिन यह एसडीके के एक नए संस्करण में केवल परिभाषित एक वर्ग का उपयोग करता है। फ्रेमवर्क पुराने सिस्टम पर मौजूद है, लेकिन फ्रेमवर्क में परिभाषित एक वर्ग नहीं करता है।

मुझे पता है कि मैं किसी प्रकार की कमजोर लिंकिंग का उपयोग करना चाहता हूं, लेकिन किसी भी दस्तावेज़ीकरण से मैं फ़ंक्शन अस्तित्व के लिए रनटाइम चेक के बारे में बातचीत पा सकता हूं - मैं कैसे जांच सकता हूं कि एक वर्ग मौजूद है?


कक्षा क्या है? शायद वहाँ अन्य workarounds हैं।
मार्सेलो कैंटोस

जवाबों:


164

TLDR

वर्तमान:

  • स्विफ्ट :if #available(iOS 9, *)
  • ओबज-सी, आईओएस :if (@available(iOS 11.0, *))
  • ओब्ज-सी, ओएस एक्स :if (NSClassFromString(@"UIAlertController"))

लिगेसी:

  • स्विफ्ट (2.0 से पहले के संस्करण) :if objc_getClass("UIAlertController")
  • ओबज-सी, आईओएस (4.2 से पहले के संस्करण) :if (NSClassFromString(@"UIAlertController"))
  • ओबज-सी, आईओएस (11.0 से पहले के संस्करण) :if ([UIAlertController class])

स्विफ्ट 2+

यद्यपि ऐतिहासिक रूप से विशिष्ट ओएस संस्करणों के बजाय क्षमताओं (या वर्ग अस्तित्व) की जांच करने की सिफारिश की गई है, लेकिन उपलब्धता की जाँच के कारण स्विफ्ट 2.0 में यह अच्छी तरह से काम नहीं करता है ।

इसके बजाय इस तरीके का उपयोग करें:

if #available(iOS 9, *) {
    // You can use UIStackView here with no errors
    let stackView = UIStackView(...)
} else {
    // Attempting to use UIStackView here will cause a compiler error
    let tableView = UITableView(...)
}

नोट: यदि आप इसके बजाय उपयोग करने का प्रयास करते हैं objc_getClass(), तो आपको निम्न त्रुटि मिलेगी:

Only 'UIAlertController' केवल iOS 8.0 या नए पर उपलब्ध है।


स्विफ्ट के पिछले संस्करण

if objc_getClass("UIAlertController") != nil {
    let alert = UIAlertController(...)
} else {
    let alert = UIAlertView(...)
}

ध्यान दें कि objc_getClass() की तुलना में अधिक विश्वसनीय है NSClassFromString()याobjc_lookUpClass()


उद्देश्य-सी, आईओएस 4.2+

if ([SomeClass class]) {
    // class exists
    SomeClass *instance = [[SomeClass alloc] init];
} else {
    // class doesn't exist
}

देखें अधिक जानकारी के लिए code007 के जवाब


ओएस एक्स या आईओएस के पिछले संस्करण

Class klass = NSClassFromString(@"SomeClass");
if (klass) {
    // class exists
    id instance = [[klass alloc] init];
} else {
    // class doesn't exist
}

का उपयोग करें NSClassFromString()। यदि यह वापस आता है nil, तो कक्षा मौजूद नहीं है, अन्यथा यह कक्षा की वस्तु को लौटा देगा जिसका उपयोग किया जा सकता है।

इस दस्तावेज़ में Apple के अनुसार यह अनुशंसित तरीका है :

[...] आपका कोड [a] वर्ग के अस्तित्व के लिए परीक्षण NSClassFromString()करेगा, जिसके उपयोग से एक वैध वर्ग वस्तु वापस आ जाएगी यदि [] वर्ग मौजूद है या शून्य नहीं है यदि वह नहीं करता है। यदि कक्षा मौजूद है, तो आपका कोड इसका उपयोग कर सकता है [...]


धन्यवाद। बस दूसरों के लिए उत्तर को पूरा करने के लिए, एक बार जब आप वर्ग का पता लगा लेते हैं तो आप इसे उस Classउदाहरण के द्वारा लौटाए गए NSClassFromString(इसे असाइन करें id) का उपयोग करके और चयनकर्ताओं को आमंत्रित करते हैं।
साइकॉटिक

2
विशेष रूप से, यह OSX पर एकमात्र तरीका है, लेकिन iOS (4.2+) पर "सबसे अच्छा" तरीका नहीं है, हालांकि यह काम करेगा। विशेष रूप से iOS के लिए code007 का उत्तर देखें।
बेन मोशर

क्या होगा यदि मेरी कक्षा एक वास्तविक वर्ग नहीं है, बल्कि सी संरचना है?
नाथन एच।

स्विफ्ट 4.1 नई जांच के साथ आ रही है canImportप्रस्ताव
प्रेषण

69

IOS 4.2 या उसके बाद के बेस SDK का उपयोग करने वाली नई परियोजनाओं के लिए, यह नया अनुशंसित तरीका है, जो कि कम समय में कमजोर लिंक वाली कक्षाओं की उपलब्धता की जांच करने के लिए NSObject क्लास पद्धति का उपयोग करना है। अर्थात

if ([UIPrintInteractionController class]) {
    // Create an instance of the class and use it.
} else {
    // Alternate code path to follow when the
    // class is not available.
}

स्रोत: https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/cross_development/Using/use.html#//apple_ref/doc/uid/20002000-SW3

यह तंत्र NS_CLASS_AVAILABLE मैक्रो का उपयोग करता है, जो iOS में अधिकांश ढांचे के लिए उपलब्ध है (ध्यान दें कि कुछ फ्रेमवर्क हो सकते हैं जो अभी तक NS_CLASS_AVAILABLE का समर्थन नहीं करते हैं - इसके लिए iOS रिलीज़ नोट की जांच करें)। अतिरिक्त सेटिंग कॉन्फ़िगरेशन की भी आवश्यकता हो सकती है जिसे ऊपर दिए गए Apple के दस्तावेज़ीकरण लिंक में पढ़ा जा सकता है, हालांकि, इस पद्धति का लाभ यह है कि आपको स्टेटिक चेकिंग की सुविधा मिलती है।


3
एक छोटी सी खेल के लिए देर हो चुकी है, लेकिन मैं तो बस जब कि निहित निर्माण कोड की कोशिश कर इस मुद्दे में भाग UIAlertControllerजबकि अभी भी आईओएस 7. code007 के जवाब सही है समर्थन है, लेकिन अतिरिक्त विन्यास की जरूरत दुर्बलता से लिंक करने के लिए (से सेट है Requiredकरने के लिए Optionalअपनी परियोजना में) UIKit (इस स्थिति के लिए, कम से कम)।
इवान आर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.