यदि आपके कोड को ऐसी सुविधा की आवश्यकता है जो केवल macOS 10.12 या नए में उपलब्ध है, लेकिन आप चाहते हैं कि आपका कोड पुराने सिस्टम संस्करणों पर भी लागू हो, तो आप उद्देश्य-सी में @available का उपयोग कर सकते हैं:

if (@available(macOS 10.12, *)) {
    // Code that requires 10.12 APIs
} else {
    // Code that doesn't require 10.12 APIs
}

आप स्विफ्ट में #available का उपयोग करके वही काम कर सकते हैं:

if #available(macOS 10.12, *) {
    // Code that requires 10.12 APIs
} else {
    // Code that doesn't require 10.12 APIs
}

लेकिन अगर आप C या C++ कोड लिखते हैं तो आप क्या उपयोग कर सकते हैं?

5
Mecki 6 सितंबर 2019, 19:36

1 उत्तर

सबसे बढ़िया उत्तर

C और C++ में आप क्लैंग कंपाइलर एक्सटेंशन __builtin_available का उपयोग कर सकते हैं:

if (__builtin_available(macOS 10.12, *)) {
    // Code that requires 10.12 APIs
} else {
    // Code that doesn't require 10.12 APIs
}

यानी अगर आपके पास कम से कम क्लैंग 5 उपलब्ध है (एक्सकोड 5.0 या नया)।

ध्यान रखें कि इस सुविधा को ठीक से काम करने के लिए आपको एक परिनियोजन लक्ष्य निर्धारित करना होगा (उदा. -mmacosx-version-min=10.9)। कारण यह है कि कमजोर लिंकिंग को कब करना है, यह तय करने के लिए लिंकर को इस जानकारी की आवश्यकता होती है। उदाहरण के लिए परिनियोजन लक्ष्य को 10.9 पर सेट करना लिंकर को बताता है कि यदि आपका कोड किसी ऐसे प्रतीक का उपयोग कर रहा है जो पहले से 10.9 में उपलब्ध नहीं था, तो इन प्रतीकों को कमजोर रूप से जोड़ा जाना चाहिए।

आम तौर पर एक निष्पादन योग्य या पुस्तकालय लोड पर सभी संदर्भित प्रतीकों को हल करने का प्रयास करेगा और यदि ऐसा कोई प्रतीक नहीं मिल पाता है तो लोड करने में विफल रहता है। हालांकि, जब कोई प्रतीक कमजोर रूप से जुड़ा होता है, तो प्रतीक को हल करने में असमर्थ होने से लोडिंग विफल नहीं होगी, इसके बजाय उस प्रतीक का कोई भी संदर्भ रनटाइम पर एक NULL संदर्भ बन जाता है। कहने की जरूरत नहीं है, यदि आप किसी ऐसे फ़ंक्शन को कॉल करने का प्रयास करते हैं जो कमजोर रूप से जुड़ा हुआ था और लोड पर नहीं मिला है, तो आपका ऐप क्रैश हो जाएगा (आप NULL को फ़ंक्शन के रूप में कॉल करने का प्रयास कर रहे हैं)। और यहीं पर __builtin_available बचाव के लिए आता है।

if (__builtin_available(macOS 10.12, *)) {
    // ...
} else {
    // Symbols only available in 10.12 or newer are all NULL when
    // you reach this code block but you wouldn't use any of them
    // in this code block, would you? So, no problem.
}

यदि आप -mmacosx-version-min का उपयोग नहीं करते हैं, तो __builtin_available निर्माण अभी भी सही ढंग से काम करेगा, फिर भी लिंकर को पता नहीं है कि आप किस प्रणाली को लक्षित कर रहे हैं, यह वर्तमान प्रणाली को मानता है और कोई कमजोर प्रदर्शन नहीं करेगा जोड़ना। यदि आप अपने ऐप को पुराने सिस्टम संस्करण पर चलाने का प्रयास करते हैं, तो कुछ प्रतीक नहीं मिलेंगे और आपका ऐप लोड होने से इंकार कर देता है, इस तथ्य के बावजूद कि उस सिस्टम के लिए वैकल्पिक कोड पथ होंगे।

8
Mecki 29 जिंदा 2021, 13:11