ब्लॉक-आधारित एपीआई विधि में गैर-अशक्त और अशक्त उद्देश्य-सी कीवर्ड का उपयोग कैसे करें


105

निम्नलिखित विधि पर विचार करें

- (void)methodWithArg:(NSString *)arg1 andArg:(NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;

नए nonnullऔर nullable एनोटेशन कीवर्ड के साथ हम इसे इस प्रकार समृद्ध कर सकते हैं:

- (void)methodWithArg:(nonnull NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;

लेकिन हमें यह चेतावनी भी मिलती है:

सूचक एक अशक्तता प्रकार विनिर्देशक (__nonnull या __nullable) याद कर रहा है

यह तीसरे पैरामीटर (ब्लॉक एक) को संदर्भित करता है।

प्रलेखन ब्लॉक मापदंडों के nullability निर्दिष्ट करने का तरीका उदाहरण के साथ कवर नहीं करता। यह शब्दशः बताता है

जब तक कोई साधारण वस्तु या ब्लॉक पॉइंटर न हो, तब तक आप एक खुले कोष्ठक के तुरंत बाद अशोभनीय रूप से अशोभनीय और अशक्त रूप में उपयोग कर सकते हैं।

मैंने बिना किसी भाग्य के ब्लॉक (किसी भी स्थिति में) के लिए दो में से एक कीवर्ड डालने की कोशिश की। अंडरस्कोर उपसर्ग वाले वेरिएंट ( __nonnullऔर __nullable) को भी आज़माया ।

इसलिए मेरा सवाल है: मैं ब्लॉक मापदंडों के लिए अशक्तता शब्दार्थ को कैसे निर्दिष्ट कर सकता हूं?

जवाबों:


128

यह काम करने लगता है

- (void)methodWithArg:(nonnull NSString *)arg1 
  andArg:(nullable NSString *)arg2 completionHandler:(nullable void (^)
  (NSArray * _Nullable results, NSError * _Nonnull error))completionHandler

आपको ब्लॉक और इसके मापदंडों दोनों के लिए अशक्तता निर्दिष्ट करने की आवश्यकता है ...

EDIT: अधिक जानकारी के लिए, स्विफ्ट ब्लॉग देखें


वह NSError **प्रकार के साथ कैसे काम करता है ? मैं संकलक को खुश करने के लिए प्रतीत नहीं कर सकता।
दुहानाबेल

3
स्विफ्ट ब्लॉग के अनुसार: The particular type NSError ** is so often used to return errors via method parameters that it is always assumed to be a nullable pointer to a nullable NSError reference. developer.apple.com/swift/blog/?id=25
user1687195

@duhanebel उत्तर stackoverflow.com/questions/33198597/… में दिया गया है : (NSError * _Nullable * _Nullable) त्रुटि
Elise van Looij

33

के अनुसार एप्पल ब्लॉग ( "Nullability और ऑब्जेक्टिव-सी") , तो आप उपयोग कर सकते हैं

NS_ASSUME_NONNULL_BEGINऔर NS_ASSUME_NONNULL_END

इन क्षेत्रों के भीतर, कोई भी सरल पॉइंटर प्रकार माना जाएगा nonnull। फिर आप बस nullableअशक्त वस्तु के लिए जोड़ सकते हैं , जो पसंद है

NS_ASSUME_NONNULL_BEGIN

@interface MyClass: NSObject

- (void)methodWithArg:(NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;

@end

NS_ASSUME_NONNULL_END
  • यदि त्रुटि है NSError **प्रकार, होना चाहिएNSError * _Nullable * _Nullable
  • यदि वस्तु id *टाइप है, तो बेहतर उपयोग id _Nullable * _Nonnull, यह निर्भर करता है (आप एक _Nullable id * _Nullableप्रकार चाहते हैं ) हो सकता है ।
  • यदि ऑब्जेक्ट NSObject *प्रकार है, तो आपको इस तरह सूचक के बाद एनोटेशन की आवश्यकता हैNSObject * _Nullable * _Nonnull

ध्यान दें

_Nonnullऔर _Nullableपॉइंटर के बाद उपयोग किया जाना चाहिए या id(उदाहरण कोड में Apple करता है AAPLListItem * _Nullable), लेकिन गैर-अंडरस्कोर किए गए फॉर्म nonnullऔर nullableएक खुले कोष्ठक के बाद उपयोग किया जा सकता है।

हालाँकि, सामान्य स्थिति में इन एनोटेशन को लिखने का एक बहुत अच्छा तरीका होता है: विधि घोषणाओं के भीतर आप गैर-अंडरस्कोर किए गए फॉर्म का उपयोग कर सकते हैं nullableऔर nonnullखुले कोष्ठक के तुरंत बाद, जब तक कि टाइप एक साधारण ऑब्जेक्ट या ब्लॉक पॉइंटर है।

"अशक्तता और उद्देश्य-सी" में अधिक जांचें

सुरक्षा के लिए, इस नियम के कुछ अपवाद हैं:

  • typedefप्रकारों में आमतौर पर एक अंतर्निहित अशक्तता नहीं होती है - वे संदर्भ के आधार पर आसानी से या तो अशक्त या गैर-अशक्त हो सकते हैं। इसलिए, अंकेक्षित क्षेत्रों के भीतर भी typedefप्रकारों को ग्रहण नहीं किया जाता है nonnull
  • अधिक जटिल सूचक प्रकार जैसे id *स्पष्ट रूप से एनोटेट होना चाहिए। उदाहरण के लिए, एक अशक्त वस्तु संदर्भ के लिए एक गैर-अशक्त सूचक निर्दिष्ट करने के लिए, उपयोग करें _Nullable id * _Nonnull
  • विशेष प्रकार NSError **का उपयोग अक्सर विधि मापदंडों के माध्यम से त्रुटियों को वापस करने के लिए किया जाता है, यह हमेशा एक अशक्त NSErrorसंदर्भ के लिए एक अशक्त सूचक माना जाता है ।

_Nullable id * _Nonnullभ्रमित किया जा सकता है, id _Nullable * _Nonnullबेहतर समझ है।

_Nonnullऔर _Nullableसूचक के बाद उपयोग किया जाना चाहिए या id(उदाहरण कोड में Apple करता हैAAPLListItem * _Nullable )


कमजोर संपत्ति के लिए, _Nullable लागू किया गया।
डोंगजिन सुह

3

आप भी ऐसा कर सकते हैं:

- (id __nullable)methodWithArg:(NSString * __nullable)arg1
                        andArg:(NSString * __nonnull)arg2
             completionHandler:(void (^ __nonnull)(NSArray * __nonnull results, NSError * __nullable error))completionHandler;

यह केवल निर्भर करता है कि आपको कौन सा वाक्यविन्यास अधिक पसंद है।


2

एक हेडर फ़ाइल में पूर्णता को परिभाषित करने के लिए मैंने ऐसा किया

typedef void (^PublicEventsHandler) (BOOL success, NSArray * _Nullable publicEvents);

बेशक, मैं स्वीकृत उत्तर से सहमत हूं।


0

सेब डेवलपर ब्लॉग से : द कोर: _Nullable और _Nonnull

जब तक कोई साधारण वस्तु या ब्लॉक पॉइंटर पॉइंटर न हो, तब तक आप एक खुले कोष्ठक के तुरंत बाद गैर-अंडरस्क्राइब किए गए फॉर्मों को अशक्त और नॉननेल का उपयोग कर सकते हैं ।

गैर-अंडरस्कोर किए गए फॉर्म अंडरस्क्राइबर्स की तुलना में अच्छे होते हैं, लेकिन फिर भी आपको उन्हें अपने हेडर में प्रत्येक प्रकार पर लागू करना होगा


हाँ, लेकिन गैर-अंडरस्कोर (अच्छे) वाले ब्लॉक घोषणाओं में काम नहीं करते हैं
पॉल ब्रूनो

-2

यहाँ मैं NSError ** मामले के लिए इस्तेमाल किया है:

-(BOOL) something:(int)number withError:(NSError *__autoreleasing  __nullable * __nullable)error;

1
जैसा कि Apple ने कहा, इसके लिए NSError **, आपको इसकी अशक्तता को निर्दिष्ट करने की कोई आवश्यकता नहीं है।
डॉनसॉन्ग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.