হ্যাঁ, instancetype
এটি প্রযোজ্য সমস্ত ক্ষেত্রেই ব্যবহার করার সুবিধা রয়েছে । আমি আরও বিশদে ব্যাখ্যা করব, তবে আমাকে এই সাহসী বক্তব্য দিয়ে শুরু করতে দাও: instancetype
এটি যখনই উপযুক্ত হয় ব্যবহার করুন , যখনই কোনও শ্রেণি একই শ্রেণীর উদাহরণ দেয় returns
আসলে, অ্যাপল এখন এই বিষয়ে যা বলেছে তা এখানে:
আপনার কোডে, যেখানে উপযুক্ত সেখানে id
রিটার্ন মান হিসাবে উপস্থিতিগুলি প্রতিস্থাপন করুন instancetype
। এটি সাধারণত init
পদ্ধতি এবং ক্লাস কারখানার পদ্ধতিগুলির ক্ষেত্রে। যদিও সংকলক স্বয়ংক্রিয়ভাবে "বরাদ্দ," "আরম্ভ," বা "নতুন" দিয়ে শুরু হওয়া পদ্ধতিগুলির রূপান্তর করে এবং ফিরে আসার মতো ধরণের id
রিটার্ন থাকে instancetype
, এটি অন্যান্য পদ্ধতিগুলিতে রূপান্তর করে না। উদ্দেশ্য-সি কনভেনশনটি instancetype
সমস্ত পদ্ধতির জন্য স্পষ্টভাবে লিখতে হয় write
উপায়টি অতিক্রম করার সাথে, আসুন এবং এটি কেন ভাল ধারণা তা ব্যাখ্যা করি।
প্রথমত, কিছু সংজ্ঞা:
@interface Foo:NSObject
- (id)initWithBar:(NSInteger)bar; // initializer
+ (id)fooWithBar:(NSInteger)bar; // class factory
@end
ক্লাস কারখানার জন্য, আপনার সর্বদা ব্যবহার করা উচিত instancetype
। কম্পাইলার স্বয়ংক্রিয়ভাবে রূপান্তর না id
করার instancetype
। যে id
একটি জেনেরিক অবজেক্ট। তবে আপনি যদি এটি একটি instancetype
সংকলক তৈরি করেন তবে পদ্ধতিটি কী ধরণের জিনিসটি ফিরে আসে তা জানে।
এই না একটি একাডেমিক সমস্যা। উদাহরণস্বরূপ, [[NSFileHandle fileHandleWithStandardOutput] writeData:formattedData]
ম্যাক ওএস এক্স-এ একটি ত্রুটি উত্পন্ন করবে ( কেবলমাত্র ) 'রাইটড্যাটা:' নামের একাধিক পদ্ধতিতে অমিল ফলাফল, প্যারামিটারের ধরন বা বৈশিষ্ট্য পাওয়া গেছে । কারণটি হ'ল এনএসফাইহ্যান্ডল এবং এনএসআরএল হ্যান্ডেল উভয়ই একটি সরবরাহ করে writeData:
। যেহেতু [NSFileHandle fileHandleWithStandardOutput]
রিটার্ন দেয় একটি id
, সংকলকটি নির্দিষ্ট নয় যে কোন শ্রেণিতে কল writeData:
করা হচ্ছে।
আপনার এই চারপাশে কাজ করা দরকার, এটি ব্যবহার করে:
[(NSFileHandle *)[NSFileHandle fileHandleWithStandardOutput] writeData:formattedData];
বা:
NSFileHandle *fileHandle = [NSFileHandle fileHandleWithStandardOutput];
[fileHandle writeData:formattedData];
অবশ্যই, আরও ভাল সমাধানটি রিটার্ন fileHandleWithStandardOutput
হিসাবে ঘোষণা করা instancetype
। তারপরে কাস্ট বা অ্যাসাইনমেন্টের প্রয়োজন নেই।
(নোট করুন যে আইওএস-এ, উদাহরণটি কেবল সেখানে NSFileHandle
সরবরাহ করে ত্রুটি তৈরি করবে না writeData:
Other অন্যান্য উদাহরণ রয়েছে যেমন length
, যা একটি CGFloat
থেকে আসে UILayoutSupport
তবে একটি NSUInteger
থেকে আসে NSString
))
দ্রষ্টব্য : যেহেতু আমি এটি লিখেছি, ম্যাকস শিরোনামগুলির NSFileHandle
পরিবর্তে একটি এর পরিবর্তে পরিবর্তন করা হয়েছে id
।
আরম্ভকারীদের জন্য, এটি আরও জটিল। আপনি যখন এটি টাইপ করবেন:
- (id)initWithBar:(NSInteger)bar
… সংকলক পরিবর্তে আপনি এটি টাইপ করে ভান করবেন:
- (instancetype)initWithBar:(NSInteger)bar
এটিআরসি-র জন্য প্রয়োজনীয় ছিল। এটিকে ঝনঝন ভাষা এক্সটেনশন সম্পর্কিত ফলাফলের ধরণগুলিতে বর্ণনা করা হয়েছে । এই কারণেই লোকেরা আপনাকে বলবে এটি ব্যবহার করার দরকার নেই instancetype
, যদিও আপনার পক্ষে হওয়া উচিত। এই উত্তরটির বাকি অংশটি এটির সাথে সম্পর্কিত।
এর তিনটি সুবিধা রয়েছে:
- স্পষ্ট। আপনার কোডটি অন্য কিছু না করে যা বলছে তাই করছে।
- প্যাটার্ন। আপনি এটি গুরুত্বপূর্ণ যে সময়ের জন্য ভাল অভ্যাস তৈরি করছেন, যা বিদ্যমান।
- সমন্নয়। আপনি আপনার কোডে কিছু ধারাবাহিকতা স্থাপন করেছেন যা এটি আরও পাঠযোগ্য।
স্পষ্ট
এটা যে কোন সত্য প্রযুক্তিগত ফিরে সুবিধার instancetype
একটি থেকে init
। কিন্তু এই কারণ কম্পাইলার স্বয়ংক্রিয়ভাবে পরিবর্তিত হয় id
থেকে instancetype
। আপনি এই বিচক্ষণতার উপর নির্ভর করছেন; আপনি যখন লিখছেন যে একটি init
ফেরত দেয় id
, সংকলক এটি ব্যাখ্যা করছে যেন এটি কোনও ফেরত দেয় instancetype
।
এগুলি সংকলকের সমতুল্য :
- (id)initWithBar:(NSInteger)bar;
- (instancetype)initWithBar:(NSInteger)bar;
এগুলি আপনার চোখের সমতুল্য নয়। সর্বোপরি, আপনি পার্থক্যটি উপেক্ষা করতে এবং এটির উপরে স্কিম শিখতে পারবেন। এটি এমন কিছু নয় যা আপনার উপেক্ষা করা শিখতে হবে।
প্যাটার্ন
যদিও সেখানে কোন পার্থক্য init
এবং অন্যান্য পদ্ধতি, সেখানে হয় তাড়াতাড়ি আপনি একটি বর্গ কারখানা সংজ্ঞায়িত হিসাবে একটি পার্থক্য।
এই দুটি সমতুল্য নয়:
+ (id)fooWithBar:(NSInteger)bar;
+ (instancetype)fooWithBar:(NSInteger)bar;
আপনি দ্বিতীয় ফর্ম চান। আপনি যদি instancetype
কোনও কনস্ট্রাক্টরের রিটার্ন টাইপ হিসাবে টাইপ করতে অভ্যস্ত হন তবে আপনি প্রতিবারই এটি পেয়ে যাবেন।
দৃঢ়তা
পরিশেষে, কল্পনা করুন আপনি যদি এটি একসাথে রাখেন: আপনি একটি init
ফাংশন এবং একটি শ্রেণিকেন্দ্রও চান want
আপনি যদি এর id
জন্য ব্যবহার করেন তবে আপনি init
এই জাতীয় কোডটি সহ শেষ করবেন:
- (id)initWithBar:(NSInteger)bar;
+ (instancetype)fooWithBar:(NSInteger)bar;
তবে আপনি যদি ব্যবহার করেন তবে আপনি এটি instancetype
পাবেন:
- (instancetype)initWithBar:(NSInteger)bar;
+ (instancetype)fooWithBar:(NSInteger)bar;
এটি আরও সামঞ্জস্যপূর্ণ এবং আরও পঠনযোগ্য। তারা একই জিনিস ফেরত দেয়, এবং এখন এটি সুস্পষ্ট।
উপসংহার
আপনি যদি ইচ্ছাকৃতভাবে পুরানো সংকলকগুলির জন্য কোডটি না লিখে থাকেন তবে instancetype
উপযুক্ত হলে আপনার ব্যবহার করা উচিত ।
ফিরে আসা কোনও বার্তা লেখার আগে আপনার দ্বিধা করা উচিত id
। নিজেকে জিজ্ঞাসা করুন: এটি কি এই শ্রেণীর কোনও উদাহরণ ফিরিয়ে দিচ্ছে? যদি তাই হয়, এটি একটি instancetype
।
কিছু ক্ষেত্রে অবশ্যই আপনাকে ফিরে যেতে id
হবে তবে আপনি সম্ভবত instancetype
আরও ঘন ঘন ব্যবহার করবেন ।