উদ্দেশ্য-সি-তে অবিচ্ছিন্ন, __nullable এবং _ ননীয় মধ্যে পার্থক্য


154

এক্সকোড .3.৩ এর সাথে ওপজেক্ট -সি-তে (এবং অবশ্যই আরও ভাল সুইফট সমর্থন নিশ্চিত করার জন্য) এপিআইয়ের অভিপ্রায়টি আরও ভালভাবে প্রকাশ করার জন্য নতুন টীকাগুলি চালু করা হয়েছিল । এই টীকা অবশ্যই ছিল nonnull, nullableএবং null_unspecified

তবে এক্সকোড with এর সাথে প্রচুর সতর্কতা উপস্থিত রয়েছে যেমন:

পয়েন্টার একটি অযোগ্যতা টাইপ স্পেসিফায়ার (_ননল, _নুলبل বা _নুল_অনস্পষ্ট) হারিয়েছে।

এগুলি ছাড়াও, অ্যাপল তাদের সি কোড ( উত্স ) চিহ্নিত করে অন্য ধরণের নালিয়াযোগ্যতা নির্দিষ্টকরণকারী ব্যবহার করে :

CFArrayRef __nonnull CFArrayCreate(
CFAllocatorRef __nullable allocator, const void * __nonnull * __nullable values, CFIndex numValues, const CFArrayCallBacks * __nullable callBacks);

সুতরাং, সংক্ষেপে বলতে গেলে, আমাদের কাছে এখন এই 3 টি পৃথক নালাব্যালি টিকা রয়েছে:

  • nonnull, nullable,null_unspecified
  • _Nonnull, _Nullable,_Null_unspecified
  • __nonnull, __nullable,__null_unspecified

যদিও আমি জানি যে কেন এবং কোথায় কোন টীকাটি ব্যবহার করতে হবে, আমি কী ধরণের টিকা ব্যবহার করব, কোথায় এবং কেন তা ব্যবহার করে কিছুটা বিভ্রান্ত হচ্ছি। এই আমি সংগ্রহ করতে পারে:

  • বৈশিষ্ট্য আমি ব্যবহার উচিত nonnull, nullable, null_unspecified
  • আমি ব্যবহার করা উচিত পদ্ধতি পরামিতি জন্য nonnull, nullable, null_unspecified
  • সি পদ্ধতি আমি ব্যবহার উচিত __nonnull, __nullable, __null_unspecified
  • যেমন ডবল পয়েন্টার আমি ব্যবহার করা উচিত অন্যান্য ক্ষেত্রে জন্য _Nonnull, _Nullable, _Null_unspecified

তবে আমি এখনও বিভ্রান্ত হয়েছি কেন আমাদের কাছে এতগুলি টিকা আছে যা মূলত একই জিনিসটি করে।

সুতরাং আমার প্রশ্নটি হ'ল:

এই টীকাগুলির মধ্যে সঠিক পার্থক্য কীভাবে, সেগুলি সঠিকভাবে কীভাবে রাখা যায় এবং কেন?


3
আমি সেই পোস্টটি পড়েছি তবে এটি পার্থক্যটি ব্যাখ্যা করে না এবং কেন এখন আমাদের 3 টি বিভিন্ন ধরণের টিকা রয়েছে এবং কেন তারা তৃতীয় প্রকারটি যুক্ত করে চলেছে তা আমি সত্যিই বুঝতে চাই।
লেগোলেস

2
এটি সত্যই @ সাই -4 এএইচ সহায়তা করে না এবং আপনি এটি জানেন। :)
লেগোলেস

@ লেগোলেস, আপনি কি নিশ্চিত যে এটি মনোযোগ দিয়ে পড়েছেন? এটি আপনাকে কোথায় এবং কীভাবে তাদের ব্যবহার করা উচিত, নিরীক্ষিত স্কোপগুলি কী, যখন আপনি অন্যটি আরও ভাল পঠনযোগ্যতা, সামঞ্জস্যতার কারণে, ইত্যাদি ইত্যাদির জন্য ব্যবহার করতে পারেন তা সুনির্দিষ্টভাবে ব্যাখ্যা করে ... আপনি কী জিজ্ঞাসা করতে চান তা আপনি জানেন না, তবে উত্তরটি লিঙ্কের নীচে রয়েছে। এটি সম্ভবত কেবল আমারই, তবে আমি মনে করি না যে তাদের উদ্দেশ্য ব্যাখ্যা করার জন্য এখানে আর কোনও ব্যাখ্যা প্রয়োজন হবে, উত্তরটি হিসাবে এখানে সরল ব্যাখ্যাটি অনুলিপি করে আটকানোটি সত্যই বিশ্রী হবে, আমার ধারণা। :(
হোলএক্স

2
এটি কিছু অংশ পরিষ্কার করে দেয়, তবে না, আমি এখনও বুঝতে পারি না কেন কেবল আমাদের প্রথম টীকা নেই। এটি কেবলমাত্র ব্যাখ্যা করে যে তারা __nullable থেকে _Nablable তে গিয়েছিল তবে কেন আমাদের এমনকি যদি আমাদের nlalable হয় তবে _ ননযোগ্যও প্রয়োজন হয় না। এবং এটি এখনও ব্যাখ্যা করে না যে অ্যাপল এখনও তাদের নিজস্ব কোডে __nlalable ব্যবহার করে।
লেগোলেস

উত্তর:


152

clang ডকুমেন্টেশন থেকে :

প্রদত্ত পয়েন্টার ধরণের মান নাল ( _Nullableকোয়ালিফায়ার) হতে পারে, নাল ( কোয়ালিফায়ার) এর কোনও সংজ্ঞায়িত অর্থ নেই _Nonnullবা যার জন্য নালটির উদ্দেশ্যটি অস্পষ্ট ( _Null_unspecifiedযোগ্যতা) । যেহেতু ন্যূনবিলিটি যোগ্যতা টাইপ সিস্টেমের মধ্যে প্রকাশ করা হয়, সেগুলি nonnullএবং returns_nonnullগুণাবলীর চেয়ে বেশি সাধারণ , যার সাহায্যে কোনও ব্যক্তিকে (উদাহরণস্বরূপ) নননাল পয়েন্টারগুলির একটি অ্যারে প্রকাশ করতে দেয় ul নুলেবিলিটি বাছাইকারীরা পয়েন্টারের যে অংশে তারা প্রয়োগ করে তার ডানদিকে লেখা হয়।

, এবং

অবজেক্টিভ-সি-তে, অযোগ্যতা যোগ্যতার জন্য একটি বিকল্প বানান রয়েছে যা উদ্দেশ্য-সি পদ্ধতিতে এবং প্রসঙ্গে সংবেদনশীল, অ-আন্ডারকর্ডেড কীওয়ার্ড ব্যবহার করে বৈশিষ্ট্যগুলিতে ব্যবহার করা যেতে পারে

সুতরাং পদ্ধতির রিটার্ন এবং প্যারামিটারগুলির জন্য আপনি একক আন্ডারসর্ডার্ডগুলির পরিবর্তে বা নন-আন্ডারস্কর্ডগুলির পরিবর্তে ডাবল-আন্ডারসর্ডার্ড সংস্করণগুলি __nonnull/ __nullable/ ব্যবহার করতে পারেন __null_unspecifiedপার্থক্যটি হ'ল একক এবং ডাবল আন্ডারকর্ডগুলি টাইপ সংজ্ঞার পরে স্থাপন করা দরকার, অন্যদিকে নন-আন্ডারস্কোরগুলি টাইপ সংজ্ঞার আগে স্থাপন করা দরকার।

সুতরাং, নিম্নলিখিত ঘোষণা সমতুল্য এবং সঠিক:

- (nullable NSNumber *)result
- (NSNumber * __nullable)result
- (NSNumber * _Nullable)result

পরামিতিগুলির জন্য:

- (void)doSomethingWithString:(nullable NSString *)str
- (void)doSomethingWithString:(NSString * _Nullable)str
- (void)doSomethingWithString:(NSString * __nullable)str

বৈশিষ্ট্যের জন্য:

@property(nullable) NSNumber *status
@property NSNumber *__nullable status
@property NSNumber * _Nullable status

ডাবল পয়েন্টার বা শূন্যতার চেয়ে আলাদা কিছু ফেরত দেওয়া ব্লকগুলি যখন জড়িত তখন বিষয়গুলি জটিল হয় কারণ নন-আন্ডারস্কোরগুলি এখানে অনুমোদিত নয়:

- (void)compute:(NSError *  _Nullable * _Nullable)error
- (void)compute:(NSError *  __nullable * _Null_unspecified)error;
// and all other combinations

ব্লকগুলিকে প্যারামিটার হিসাবে গ্রহণ করে এমন পদ্ধতির সাথে অনুরূপ, দয়া করে নোট করুন nonnull/ nullableযোগ্যতাটি ব্লকের ক্ষেত্রে প্রযোজ্য, এবং তার ফেরতের প্রকার নয়, সুতরাং নিম্নলিখিতটি সমতুল্য:

- (void)executeWithCompletion:(nullable void (^)())handler
- (void)executeWithCompletion:(void (^ _Nullable)())handler
- (void)executeWithCompletion:(void (^ __nullable)())handler

যদি ব্লকের কোনও ফেরতের মান থাকে তবে আপনাকে বাধ্যতামূলকভাবে আন্ডারস্কোর সংস্করণগুলির মধ্যে একটিতে বাধ্য করা হবে:

- (void)convertObject:(nullable id __nonnull (^)(nullable id obj))handler
- (void)convertObject:(id __nonnull (^ _Nullable)())handler
- (void)convertObject:(id _Nonnull (^ __nullable)())handler
// the method accepts a nullable block that returns a nonnull value
// there are some more combinations here, you get the idea

উপসংহার হিসাবে, আপনি যেকোন একটি ব্যবহার করতে পারবেন, যতক্ষণ সংকলক আইটেমটি যোগ্যতা নির্ধারণের জন্য নির্ধারণ করতে পারে।


2
দেখে মনে হচ্ছে যে আন্ডারস্কোর সংস্করণগুলি যে কোনও জায়গায় ব্যবহার করা যেতে পারে, তাই আমি মনে করি যে আমি অন্য জায়গায় আন্ডারস্কোর ছাড়াই কিছু জায়গায় আন্ডারস্কোর করা সংস্করণ ব্যবহার না করে ধারাবাহিকভাবে সেগুলি ব্যবহার করব। সঠিক?
ভাদ্দাদি কার্তিক

@ কার্টিকভাদাদি হ্যাঁ, ঠিক আছে, আপনি নিয়মিতভাবে একক আন্ডারকর্ডড, বা ডাবল আন্ডারকর্ডেড সংস্করণগুলি ব্যবহার করতে পারেন।
ক্রিশ্তিক

_Null_unspecifiedসুইফ্ট এ এই optionচ্ছিক অনুবাদ? অ-alচ্ছিক বা কী?
মধু

1
@ মধু _নুল_অনস্পষ্টিত সুস্পিটে ইম্প্রিসিটেলি আনরোপড অপশনাল হিসাবে আমদানি করা হয়েছে
ক্রিশটিক

1
পছন্দ করুন আমার মনে হয় এটির ডিফল্ট মান ... কারণ যখন আমি নির্দিষ্ট না করলাম তখন আমি স্পষ্টতই মোড়কানো optionচ্ছিকভাবে পেয়ে যাচ্ছিলাম ...
হানি

28

থেকে সুইফট ব্লগ :

এই বৈশিষ্ট্যটি প্রথমে এক্সকোড 6.3 এ __nullable এবং __nnull কীওয়ার্ড সহ প্রকাশিত হয়েছিল। তৃতীয় পক্ষের লাইব্রেরিগুলির সাথে সম্ভাব্য দ্বন্দ্বের কারণে, আমরা এগুলিকে Xcode 7 এ পরিবর্তন করে _নুলযোগ্য এবং _নানল আপনি এখানে দেখতে পেয়েছেন। যাইহোক, এক্সকোড 6.3 এর সাথে সামঞ্জস্যের জন্য আমরা নতুন নামগুলিতে প্রসারিত করার জন্য ম্যাক্রোগুলি __nullable এবং __nnull পূর্বনির্ধারিত করেছি।


4
সংক্ষেপে, একক এবং ডাবল আন্ডারস্কোর সংস্করণগুলি অভিন্ন।
ভাদ্দাদি কার্টিক

4
এক্সকোড .0.০ রিলিজ নোটেও নথিবদ্ধভাবে নথিভুক্ত করা হয়েছে: "ডাবল-আন্ডারস্কর নল্যাবিলিটি যোগ্যতা (__nullable, __nnull এবং __null_unspecified) একটি মূল অক্ষর সহ একটি একক আন্ডারস্কোর ব্যবহার করার জন্য পুনরায় নামকরণ করা হয়েছে: _নুলযোগ্য, _ ননল, এবং _ নল_সঙ্কিত, যথাক্রমে সংকলক পূর্ববর্তীগুলি। উত্সের সামঞ্জস্যের জন্য পুরানো ডাবল-অনির্দিষ্ট নাম থেকে নতুন নামগুলিতে ম্যাপিং ("(21530726)"
কোসিন

25

আমি এই নিবন্ধটি সত্যিই পছন্দ করেছি , তাই লেখক যা লিখেছেন তা কেবল আমি প্রদর্শন করছি: https://swiftunboxed.com/interop/objc-nullability-annotations/

  • null_unspecified:একটি সুইফটে ব্রিজগুলি সুস্পষ্টভাবে-মোড়কযুক্ত optionচ্ছিক। এটি ডিফল্ট
  • nonnull: মান শূন্য হবে না; একটি নিয়মিত রেফারেন্স সেতু।
  • nullable: মান শূন্য হতে পারে; একটি alচ্ছিক ব্রিজ।
  • null_resettable: পড়ার সময় মানটি কখনই শূন্য হয় না তবে এটি পুনরায় সেট করতে আপনি এটি শূন্য করতে পারেন। শুধুমাত্র বৈশিষ্ট্যের ক্ষেত্রে প্রযোজ্য।

উপরের স্বরলিপিগুলি, তারপরে আপনি সেগুলি বৈশিষ্ট্য বা ফাংশন / ভেরিয়েবলের প্রসঙ্গে ব্যবহার করেন কিনা তা থেকে পৃথক করুন :

পয়েন্টার বনাম বৈশিষ্ট্য চিহ্নিতকরণ

নিবন্ধটির লেখক একটি দুর্দান্ত উদাহরণও দিয়েছেন:

// property style
@property (nonatomic, strong, null_resettable) NSString *name;

// pointer style
+ (NSArray<NSView *> * _Nullable)interestingObjectsForKey:(NSString * _Nonnull)key;

// these two are equivalent!
@property (nonatomic, strong, nullable) NSString *identifier1;
@property (nonatomic, strong) NSString * _Nullable identifier2;

12

খুব সহজ

NS_ASSUME_NONNULL_BEGIN 

এবং সাথে বন্ধ

NS_ASSUME_NONNULL_END 

এটি কোড স্তরের 'নুলিবিস' :-) এর প্রয়োজনীয়তা বাতিল করে দেবে কারণ এটি অনুমান করা যায় যে অন্যথায় উল্লিখিত না হলে সমস্ত কিছু নাল ( nonnullবা _nonnullবা __nonnull) হয় না।

দুর্ভাগ্যক্রমে এর ব্যতিক্রমও রয়েছে ...

  • typedefs হিসাবে ধরে নেওয়া হয় না __nonnull(দ্রষ্টব্য, কাজ nonnullকরে বলে মনে হচ্ছে না, এটি কুৎসিত অর্ধেক ভাই ব্যবহার করতে হবে)
  • id *একটি সুস্পষ্ট নুলিবি প্রয়োজন তবে পাপ করের বাহ ( _Nullable id * _Nonnull<- এর অর্থ কী অনুমান করুন ...)
  • NSError ** সর্বদা nallable ধরে নেওয়া হয়

সুতরাং ব্যতিক্রমগুলি ব্যতিক্রম এবং একই কার্যকারিতা থেকে বেরিয়ে আসা অসঙ্গতিপূর্ণ কীওয়ার্ডগুলির সাথে, সম্ভবত সংযোগকারী অভিযোগ করলে কুৎসিত সংস্করণগুলি __nonnull/ __nullable/ __null_unspecifiedএবং অদলবদল করার পদ্ধতিটি সম্ভবত ব্যবহার করা ...? সম্ভবত সে কারণেই তারা অ্যাপল হেডারগুলিতে উপস্থিত রয়েছে?

আকর্ষণীয়ভাবে যথেষ্ট, কোনও কিছু এটি আমার কোডে ফেলেছে ... আমি কোডকে ঘৃণা করি (পুরানো স্কুল অ্যাপল সি ++ শৈলীর লোক) তাই আমি নিশ্চিত যে আমি এগুলি টাইপ করি নি তবে তারা উপস্থিত হয়েছিল (বেশ কয়েকটি উদাহরণের একটি উদাহরণ):

typedef void ( ^ DidReceiveChallengeBlock ) ( NSURLSessionAuthChallengeDisposition disposition,
                                          NSURLCredential * __nullable credential );

এবং আরও মজার বিষয়, যেখানে এটি __ প্রবেশ করানো ভুল তা ভুল in ... (অবশ্যই @!)

আমি সত্যই কামনা করি যে আমি কেবল নন-আন্ডারস্কোর সংস্করণটি ব্যবহার করতে পারব তবে স্পষ্টতই এটি একটি ত্রুটি হিসাবে চিহ্নিত করা হয়েছে বলে সংকলকটির সাথে উড়ে যায় না:

typedef void ( ^ DidReceiveChallengeBlock ) ( NSURLSessionAuthChallengeDisposition disposition,
                                          NSURLCredential * nonnull  credential );

2
। অ আন্ডারস্কোর শুধুমাত্র অর্থাত (nonnull ... শুধু জীবন আরো আকর্ষণীয় করা, আমি নিশ্চিত খোলা প্রথম বন্ধনী পরে সরাসরি ব্যবহার করা যেতে পারে
এলিস ভ্যান Looij

আমি কীভাবে একটি আইডি করব <> ননল? আমি মনে করি এই উত্তরটিতে প্রচুর জ্ঞান রয়েছে তবে এতে স্বচ্ছতার অভাব রয়েছে।
fizzybear

1
@ ফিজিবিয়ার স্বীকার করেছেন আমি সাধারণত বিপরীত পন্থা অবলম্বন করি। পয়েন্টারগুলি আমার বন্ধু এবং 90 এর দশকের গোড়ার দিকে আমার "নাল" / "নীল" পয়েন্টার সমস্যা নেই। আমি আশা করি আমি পুরো আটকানো / আটকানো জিনিসটি কেবল দূরে সরিয়ে ফেলতে পারতাম। তবে বিন্দুতে, আসল উত্তরটি উত্তর উত্তরের প্রথম 6 লাইনে রয়েছে। তবে আপনার প্রশ্ন সম্পর্কে: আমি কিছু করব না (সমালোচনা করবেন না) তাই আমি জানি না।
উইলিয়াম Cerniuk
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.