আসুন retain
এবং দিয়ে শুরু করা যাক release
; autorelease
আপনি মৌলিক ধারণাটি বুঝতে পারলে সত্যিই এটি একটি বিশেষ কেস।
কোকোয়, প্রতিটি বস্তু এটি কতবার রেফারেন্স করা হচ্ছে তা ট্র্যাক করে রাখে (বিশেষত, NSObject
বেস শ্রেণি এটি প্রয়োগ করে)। retain
কোনও বস্তুর উপর কল করে, আপনি এটি বলছেন যে আপনি একে একে এর রেফারেন্স গণনা আপ করতে চান। কল করে release
, আপনি যে অবজেক্টটি তা ছাড়তে দিচ্ছেন তা বলুন এবং এর রেফারেন্স গণনা হ্রাস পেয়েছে। যদি, কল করার পরে release
, রেফারেন্স গণনাটি এখন শূন্য হয়, তবে সেই বস্তুর মেমরিটি সিস্টেম দ্বারা মুক্ত হয়।
এটির মূল উপায়টি এর থেকে পৃথক malloc
এবং free
এটি হ'ল যে কোনও প্রদত্ত বস্তুকে সিস্টেমের ক্র্যাশ হওয়ার অন্যান্য অংশগুলি নিয়ে চিন্তা করার দরকার নেই কারণ আপনি যে স্মৃতি ব্যবহার করেছিলেন তা সেগুলি মুক্ত করেছেন। সবাই ধরে নিচ্ছেন যে নিয়ম অনুসারে খেলছেন এবং ধরে রাখছেন / ছাড়ছেন, যখন কোডের এক টুকরা অবজেক্টটি বজায় রাখে এবং তারপরে অবজেক্টটি প্রকাশ করে, অন্য কোনও কোডের টুকরাও অবজেক্টটিকে রেফারেন্স করবে না।
কখনও কখনও বিভ্রান্তিকর কি হতে পারে সেই পরিস্থিতিতে আপনার কী পরিস্থিতিতে কল করা উচিত retain
এবং তা জানা উচিত release
। আমার থাম্বের সাধারণ নিয়মটি হ'ল যদি আমি কিছু সময়ের জন্য কোনও বস্তুর সাথে আটকে থাকতে চাই (উদাহরণস্বরূপ এটি যদি কোনও শ্রেণীর সদস্য ভেরিয়েবল হয়), তবে আমাকে নিশ্চিত করতে হবে যে অবজেক্টের রেফারেন্স গণনাটি আমার সম্পর্কে জানে। উপরে বর্ণিত হিসাবে, কোনও বস্তুর রেফারেন্স গণনা কল করে বৃদ্ধি করা হয় retain
। কনভেনশন অনুসারে, বস্তুটি যখন "init" পদ্ধতিতে তৈরি করা হয় তখন এটি বৃদ্ধিও হয় (1 এ সেট করা হয়, সত্যই)। এই দুটি ক্ষেত্রেই, আমার release
যখন দায়িত্বটি শেষ হয়ে যায় তখন তার সাথে যোগাযোগ করা আমার দায়িত্ব । যদি আমি না করি তবে একটি স্মৃতি ফাঁস হবে।
বস্তু তৈরির উদাহরণ:
NSString* s = [[NSString alloc] init]; // Ref count is 1
[s retain]; // Ref count is 2 - silly
// to do this after init
[s release]; // Ref count is back to 1
[s release]; // Ref count is 0, object is freed
এখন জন্য autorelease
। অটোরিলেজকে কিছুক্ষণ পরে এই অবজেক্টটি মুক্ত করতে সিস্টেমটিকে বলার সুবিধার (এবং কখনও কখনও প্রয়োজনীয়) উপায় হিসাবে ব্যবহৃত হয়। নদীর গভীরতানির্ণয় দৃষ্টিকোণ থেকে, যখন autorelease
ডাকা হয়, বর্তমান থ্রেডগুলি NSAutoreleasePool
কল সম্পর্কে সতর্ক করা হয়। NSAutoreleasePool
এখন জানে যে একবার এটি একটি সুযোগ (ঘটনা লুপ বর্তমান পুনরাবৃত্তির পর) পায়, এটি কল করতে পারেন release
বস্তুর উপর। প্রোগ্রামার হিসাবে আমাদের দৃষ্টিকোণ থেকে, এটি release
আমাদের জন্য আহ্বান যত্ন নেয় , যাতে আমাদের করতে হবে না (এবং বাস্তবে আমাদের উচিত নয়) should
সবচেয়ে গুরুত্বপূর্ণ যেটি মনে রাখা দরকার তা হ'ল (আবার কনভেনশন অনুসারে) সমস্ত অবজেক্ট তৈরি শ্রেণি পদ্ধতিগুলি একটি স্বতঃস্ফূর্ত বিষয়টিকে ফেরত দেয়। উদাহরণস্বরূপ, নিম্নলিখিত উদাহরণে, ভেরিয়েবল "s" এর 1 এর রেফারেন্স গণনা রয়েছে তবে ইভেন্ট লুপটি সম্পূর্ণ হওয়ার পরে এটি ধ্বংস হয়ে যাবে।
NSString* s = [NSString stringWithString:@"Hello World"];
আপনি যদি সেই স্ট্রিংটিতে ঝুলতে চান তবে আপনার retain
স্পষ্টভাবে কল করতে হবে এবং release
আপনার কাজ শেষ হয়ে গেলে এটি স্পষ্টতই কল করতে হবে।
নিম্নলিখিত (খুব স্বীকৃত) বিট কোডটি বিবেচনা করুন এবং আপনি এমন পরিস্থিতি দেখতে পাবেন যেখানে autorelease
প্রয়োজন:
- (NSString*)createHelloWorldString
{
NSString* s = [[NSString alloc] initWithString:@"Hello World"];
// Now what? We want to return s, but we've upped its reference count.
// The caller shouldn't be responsible for releasing it, since we're the
// ones that created it. If we call release, however, the reference
// count will hit zero and bad memory will be returned to the caller.
// The answer is to call autorelease before returning the string. By
// explicitly calling autorelease, we pass the responsibility for
// releasing the string on to the thread's NSAutoreleasePool, which will
// happen at some later time. The consequence is that the returned string
// will still be valid for the caller of this function.
return [s autorelease];
}
আমি বুঝতে পারছি এগুলি কিছুটা বিভ্রান্তিকর - কিছু সময় এটি ক্লিক করবে। আপনাকে যেতে কয়েকটি রেফারেন্স এখানে দেওয়া হয়েছে: