কোকো এবং উদ্দেশ্য-সি এর সাথে রেফারেন্স গণনা বোঝা


122

আইফোন এসডিকে নিয়ে খেলার দৃষ্টিভঙ্গি নিয়ে আমি কেবল অবজেক্টিভ-সি এবং কোকোতে নজর রাখতে শুরু করেছি। আমি সি mallocএবং freeধারণা নিয়ে যুক্তিযুক্ত আরামদায়ক , কিন্তু কোকো রেফারেন্স গণনা স্কিম আমাকে বরং বিভ্রান্ত করেছে। আমাকে জানানো হয়েছে এটি একবার আপনি এটি বুঝতে পারলে এটি খুব মার্জিত, তবে আমি এখনও কুঁড়ির উপরে নেই।

কীভাবে release, retainএবং autoreleaseকাজ করে এবং তাদের ব্যবহার সম্পর্কে কনভেনশনগুলি কী কী?

(বা এটি ব্যর্থ হয়ে আপনি কী পড়েন যা আপনাকে এটি পেতে সহায়তা করেছিল?)

উত্তর:


148

আসুন 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];
}

আমি বুঝতে পারছি এগুলি কিছুটা বিভ্রান্তিকর - কিছু সময় এটি ক্লিক করবে। আপনাকে যেতে কয়েকটি রেফারেন্স এখানে দেওয়া হয়েছে:


8
আপনি লিখেছেন: "স্বতঃপরিচয় কল করে আমরা অস্থায়ীভাবে রেফারেন্স গণনাটি টুকরো টুকরো করে"। আমি মনে করি এটি ভুল; অটোরিলেজ কেবল ভবিষ্যতে প্রকাশিত হওয়া অবজেক্টটিকে চিহ্নিত করে, এটি রেফ গণনা বাড়ায় না: cocoadev.com/index.pl? অটোআরিজ
LKM

2
"এখন অটোরিলেজের জন্য Aut কিছুক্ষণ পরে এই বিষয়টিকে মুক্ত করার জন্য সিস্টেমকে বলার জন্য অটোরলেজ সুবিধাজনক (এবং কখনও কখনও প্রয়োজনীয়) উপায় হিসাবে ব্যবহৃত হয়" " লিড-ইন বাক্য হিসাবে, এটি ভুল। এটি সিস্টেমটিকে "মুক্ত [এটি]" করতে বলছে না, এটি ধরে রাখার গণনা হ্রাস করতে বলে।
এমএমএলসি

3
ভাল ব্যাখ্যার জন্য অনেক ধন্যবাদ। একটি মাত্র বিষয় যা এখনও অস্পষ্ট। যদি NSString* s = [[NSString alloc] initWithString:@"Hello World"];একটি স্বতঃস্ফূর্ত অবজেক্ট (যদি আপনি এটি লিখেন) ফেরত দেয় তবে কেন আমাকে একটি করতে হবে return [s autorelease];এবং এটিকে আবার "অটোরেলিজ" সেট করতে হবে এবং ঠিক নয় return s?
znq

3
@ স্টেফান: [[NSString alloc] initWithString:@"Hello World"]একটি স্বতঃপ্রযুক্ত বস্তু ফেরত দেবে না। যখনই allocডাকা হয়, রেফারেন্স গণনাটি 1 তে সেট করা থাকে এবং এটি প্রকাশিত হয় তা নিশ্চিত করা এই কোডটির দায়িত্ব। [NSString stringWithString:]কল, অন্যদিকে নেই একটি autoreleased বস্তুর ফিরে যান।
ম্যাট ডিলার্ড

6
মজাদার ট্রিভিয়া: যেহেতু উত্তরটি "" "এবং এনএসএসস্ট্রিং ব্যবহার করে, তারপরে স্ট্রিংগুলি ধ্রুবক এবং এইভাবে, নিরঙ্কুশ ধরে রাখা গণনা উভয় ধ্রুবক এবং সম্পূর্ণ অপ্রাসঙ্গিক হবে .... কোনওভাবেই উত্তরটিকে ভুল করে না, ঠিক নিরঙ্কুশ ধরে রাখা গণনাগুলি সত্যই এমন কিছু নয় যা আপনার চিন্তা করা উচিত rein
বুবুম

10

যদি আপনি ধরে রাখার / প্রকাশের প্রক্রিয়াটি বুঝতে থাকেন তবে দুটি সুবর্ণ নিয়ম রয়েছে যা প্রতিষ্ঠিত কোকো প্রোগ্রামারদের কাছে "দুহ" সুস্পষ্ট, তবে দুর্ভাগ্যক্রমে খুব কমই নতুনদের জন্য এটিকে স্পষ্টভাবে বানান করা হয়েছে।

  1. একটি ফাংশন যা একটি বস্তু ফেরৎ থাকে alloc, createবা copyএর নাম তারপর বস্তু আপনার। [object release]এটি শেষ হলে আপনার অবশ্যই কল করা উচিত । অথবা CFRelease(object), যদি এটি একটি কোর-ফাউন্ডেশন অবজেক্ট।

  2. যদি এর নামে এই শব্দগুলির একটিও না থাকে তবে অবজেক্টটি অন্য কারওর। আপনি [object retain]যদি আপনার ফাংশন শেষ হওয়ার পরে অবজেক্টটি রাখতে চান তবে আপনাকে অবশ্যই কল করতে হবে।

আপনি নিজের তৈরি ফাংশনগুলিতে এই সম্মেলনটি অনুসরণ করার জন্য আপনাকে ভাল পরিবেশিত হবে।

(নিতপিকার্স: হ্যাঁ, দুর্ভাগ্যক্রমে কয়েকটি এপিআই কল রয়েছে যা এই নিয়মের ব্যতিক্রম তবে সেগুলি বিরল)।


11
এটি অসম্পূর্ণ এবং ভুল। লোকেরা কেবল প্রাসঙ্গিক ডকুমেন্টেশনের দিকে ইঙ্গিত করার পরিবর্তে কেন নিয়মগুলি
পুনরুদ্ধার

4
বিশেষত কোর ফাউন্ডেশনের নিয়মগুলি কোকো থেকে পৃথক; দেখতে developer.apple.com/documentation/CoreFoundation/Conceptual/...
mmalc

1
আমিও একমত না যদি কোনও ফাংশন এমন কিছু ফিরিয়ে দেয় যা এটি মালিকানা চায় না, তবে এটি এটি স্বতঃপ্রণোদিত হওয়া উচিত। এটি ধরে রাখার জন্য ফাংশন কাজের কলার (যদি ইচ্ছা হয়)। যে কোনও পদ্ধতির নাম চাওয়া হচ্ছে তার সাথে কিছু করার দরকার নেই। এটি আরও সি ​​স্টাইল কোডিং যেখানে বস্তুর মালিকানা অস্পষ্ট।
স্যাম

1
দুঃখিত! আমি মনে করি ডাউন-ভোটিংয়ে আমি তাড়াহুড়ো করেছিলাম। মেমরি ম্যানেজমেন্টের নিয়ম আপনার উত্তরটি আপেল ডকটির প্রায় উদ্ধৃতি দেয়।
স্যাম

8

আপনি যদি ডেস্কটপের জন্য কোড লিখছেন এবং আপনি ম্যাক ওএস এক্স 10.5 লক্ষ্য করতে পারেন, আপনার কমপক্ষে উদ্দেশ্য-সি আবর্জনা সংগ্রহ ব্যবহার করা উচিত using এটি আপনার বেশিরভাগ বিকাশকে সত্যই সরল করে দেবে - এজন্য অ্যাপল এটিকে প্রথম স্থানে তৈরি করতে এবং এটিকে আরও ভাল করে সম্পাদন করার জন্য সমস্ত প্রচেষ্টা রেখেছিল।

জিসি ব্যবহার না করার সময় মেমরি পরিচালনার নিয়ম হিসাবে:

  • আপনি ব্যবহার করে একটি নতুন বস্তু তৈরি করেন +alloc/+allocWithZone:, +new, -copyবা -mutableCopyঅথবা যদি আপনি -retainএকটি বস্তু, আপনি এটি মালিকানা গ্রহণ করা হয় এবং অবশ্যই নিশ্চিত করতে হবে এটা পাঠানো হয় -release
  • আপনার যদি অন্য কোন ভাবে একটি বস্তুর পান তাহলে তুমি না তা মালিক এবং উচিত না নিশ্চিত করুন যে এটি পাঠানো হয় -release
  • যদি আপনি নিশ্চিত করতে চান যে কোনও বস্তু প্রেরণ করা হয়েছে -releaseআপনি তা নিজেই প্রেরণ করতে পারেন বা আপনি অবজেক্টটি প্রেরণ করতে পারেন -autoreleaseএবং পুলটি নিষ্কাশিত হওয়ার পরে বর্তমান অটোরিলিজ পুলটি এটি -release(একবার প্রাপ্ত হিসাবে একবার -autorelease) প্রেরণ করবে ।

সাধারণত -autoreleaseঘটনাটির দৈর্ঘ্যের জন্য অবজেক্টগুলি বেঁচে থাকার বিষয়টি নিশ্চিত করার একটি উপায় হিসাবে ব্যবহৃত হয় তবে পরে পরিষ্কার করা হয়, কারণ কোকো ইভেন্ট প্রসেসিংকে ঘিরে একটি অটোরিলেজ পুল রয়েছে। কোকো, এটা পর্যন্ত একজন আহবানকারীকে তুলনায় এটি যে আহ্বানকারী নিজেই মুক্তি দরকার objets আসতে হয় autoreleased হয় যে বস্তু ফিরতে আরো সাধারণ।


6

অবজেক্টিভ-সি রেফারেন্স কাউন্টিং ব্যবহার করে যার অর্থ প্রতিটি বস্তুর একটি রেফারেন্স গণনা রয়েছে। যখন কোনও বস্তু তৈরি করা হয়, তখন এটিতে "1" এর রেফারেন্স গণনা থাকে। সহজ কথায় বলতে গেলে, যখন কোনও বস্তুকে রেফারেন্স করা হয় (অর্থাত্ কোথাও সঞ্চিত থাকে), তখন এটি "ধরে রাখা" হয়ে যায় যার অর্থ এর রেফারেন্সের গণনা এক দ্বারা বাড়ানো হয়। যখন কোনও অবজেক্টের আর প্রয়োজন হয় না, তখন এটি "রিলিজ করা হয়" যার অর্থ এর রেফারেন্স গণনা হ্রাস পেয়ে এক হয়।

যখন কোনও বস্তুর রেফারেন্স গণনা 0 হয়, তখন অবজেক্টটি মুক্ত হয়। এটি মৌলিক রেফারেন্স গণনা।

কিছু ভাষার ক্ষেত্রে, উল্লেখগুলি স্বয়ংক্রিয়ভাবে বৃদ্ধি এবং হ্রাস হয়, তবে উদ্দেশ্য-সি সেই ভাষাগুলির একটি নয়। সুতরাং প্রোগ্রামার ধরে রাখা এবং ছেড়ে দেওয়ার জন্য দায়বদ্ধ।

একটি পদ্ধতি লেখার একটি সাধারণ উপায় হ'ল:

id myVar = [someObject someMessage];
.... do something ....;
[myVar release];
return someValue;

কোডের অভ্যন্তরে যে কোনও অর্জিত সংস্থানগুলি স্মরণে রাখার প্রয়োজন মনে করার সমস্যাটি উভয়ই ক্লান্তিকর এবং ত্রুটি-প্রবণ। অবজেক্টিভ-সি এটিকে আরও সহজ করে তোলার উদ্দেশ্যে আরেকটি ধারণা প্রবর্তন করেছে: অটোরেলেস পুল। অটোরিলেজ পুলগুলি এমন বিশেষ অবজেক্ট যা প্রতিটি থ্রেডে ইনস্টল করা থাকে। আপনি যদি এনএসআউটোরেলিজপুল সন্ধান করেন তবে এগুলি মোটামুটি সহজ বর্গ।

যখন কোনও বস্তু এতে একটি "অটোরিলেজ" বার্তা প্রেরণ করবে, তখন অবজেক্টটি এই বর্তমান থ্রেডের জন্য স্ট্যাকের উপর বসে কোনও অটোরলেজ পুলের সন্ধান করবে। এটি ভবিষ্যতে কোনও সময়ে "রিলিজ" বার্তা প্রেরণ করার জন্য একটি অবজেক্ট হিসাবে তালিকায় এই বস্তুকে যুক্ত করবে, সাধারণত পুলটি যখন প্রকাশ হয় তখনই হয়।

উপরের কোডটি গ্রহণ করে, আপনি এটিকে ছোট করে এবং আরও সহজে পড়তে আরও সহজে লিখে আবার লিখতে পারেন:

id myVar = [[someObject someMessage] autorelease];
... do something ...;
return someValue;

যেহেতু বস্তুটি স্বতঃস্ফূর্ত, তাই আমাদের আর এটির উপর স্পষ্টভাবে "রিলিজ" কল করার দরকার নেই। এটি কারণ আমরা জানি যে কিছু অটোরিলেজ পুল এটি আমাদের জন্য পরে করবে।

আশা করি এটি সাহায্য করবে। রেফারেন্স গণনা সম্পর্কে উইকিপিডিয়া নিবন্ধটি বেশ ভাল। অটোরিলেজ পুল সম্পর্কে আরও তথ্য এখানে পাওয়া যাবে । এছাড়াও মনে রাখবেন যে আপনি যদি ম্যাক ওএস এক্স 10.5 এবং তার পরে তৈরি করছেন তবে আপনি এক্সকোডকে আবর্জনা সংগ্রহ সক্ষম করার সাথে তৈরি করতে বলতে পারবেন, যাতে আপনাকে রক্ষণ / প্রকাশ / অটোরিলেজ সম্পূর্ণ উপেক্ষা করতে দেয়।


2
এটা ঠিক ভুল। দেখানো উদাহরণগুলির মধ্যে কোনওটিতে অবজেক্ট রিলিজ বা অটোরলেজ প্রেরণের দরকার নেই।
ম্যামাল্যাক

6

জোশুয়া (# 6591) - ম্যাক ওএস এক্স 10.5 এর আবর্জনা সংগ্রহের সামগ্রীগুলি দুর্দান্ত মনে হচ্ছে তবে এটি আইফোনের জন্য উপলভ্য নয় (বা আপনি যদি চান আপনার অ্যাপটি ম্যাক ওএস এক্স এর প্রাক-10.5 সংস্করণে চালিত হয়)।

এছাড়াও, আপনি যদি কোনও লাইব্রেরি লিখেন বা এমন কিছু যা আবার ব্যবহার করা যেতে পারে, জিসি মোড ব্যবহার করে কোডটি ব্যবহার করে যে কাউকে লক করে এটিও জিসি মোড ব্যবহার করে, যাতে আমি এটি বুঝতে পারি, যে কেউ বিস্তৃতভাবে পুনরায় ব্যবহারযোগ্য কোডটি লেখার চেষ্টা করছেন তা পরিচালনার দিকে ঝোঁকে মেমোরি নিজেই।


2
এমন একটি হাইব্রিড কাঠামো লিখতে পুরোপুরি সম্ভব যা জিসি এবং রেফারেন্স উভয়ই গণনা সমর্থন করে।
এমএমএলসি

6

যথারীতি, লোকেরা যখন রেফারেন্স উপাদানগুলিতে পুনরায় শব্দ লেখার চেষ্টা শুরু করে তখন তারা প্রায় সবসময়ই কিছু ভুল হয়ে যায় বা একটি অসম্পূর্ণ বিবরণ সরবরাহ করে।

অ্যাপল কোকোর জন্য মেমরি ম্যানেজমেন্ট প্রোগ্রামিং গাইডে কোকো এর মেমরি ম্যানেজমেন্ট সিস্টেমের একটি সম্পূর্ণ বিবরণ প্রদান করে, যার শেষে মেমরি ম্যানেজমেন্ট বিধিগুলির একটি সংক্ষিপ্ত তবে সঠিক সংক্ষিপ্তসার উপস্থিত রয়েছে ।




2
প্রকৃতপক্ষে এটি একক পৃষ্ঠার আরও ভাল সংক্ষিপ্তসার: বিকাশকারী
অ্যাপ্লিকেশন / ম্যাক / লাইবারি / ডকুমেন্টেশন / কোকো / কনসেপ্টুয়াল / /

6

আপনি ৫০ ডলার বাদ দেওয়ার এবং হিলিগাস বইটি পাওয়ার বিষয়ে ভাবতে চাইতেই আমি অন্য কোনও রক্ষণ / প্রকাশের সুনির্দিষ্ট সংযোজন করব না, তবে আমি আপনার অ্যাপ্লিকেশনটির বিকাশের খুব তাড়াতাড়ি ইনস্ট্রুমেন্টস সরঞ্জামগুলি ব্যবহার করার বিষয়ে দৃ into়ভাবে পরামর্শ দেব (এমনকি আপনার প্রথমটি!). এটি করতে, চালান-> পারফরম্যান্স সরঞ্জাম দিয়ে শুরু করুন। আমি লিক দিয়ে শুরু করব যা কেবলমাত্র উপলব্ধ কয়েকটি যন্ত্রের মধ্যে একটি তবে আপনি যখন প্রকাশ করতে ভুলে গেছেন তখন আপনাকে দেখাতে সহায়তা করবে। আপনার কতটা তথ্য উপস্থাপন করা হবে তা হতাশ করে ছেড়ে দেওয়া। তবে উঠতে এবং দ্রুত যেতে এই টিউটোরিয়ালটি দেখুন:
কোকো টিউটোরিয়াল: ফিক্সিং মেমরি ইনস্ট্রুমেন্টসের সাথে ফাঁস হয়

প্রকৃতপক্ষে ফাঁসকে জোর করার চেষ্টা করা আরও ভাল উপায় হতে পারে, পরিবর্তে, কীভাবে সেগুলি রোধ করা যায় তা শিখতে! শুভকামনা;)


5

ম্যাট ডিলার্ড লিখেছেন :

প্রত্যাবর্তন [[এর স্বতঃপ্রকাশ] মুক্তি];

অটোরিলেজ বস্তুটি ধরে রাখে না । অটোরিলেজ এটিকে পরে প্রকাশের জন্য কাতারে রাখে। আপনি সেখানে রিলিজের বিবৃতি রাখতে চান না।




4

নীলবজেক্টের উত্তরটি একটি ভাল শুরু। ম্যানুয়াল মেমরি পরিচালনা সম্পর্কিত কিছু পরিপূরক তথ্য এখানে রয়েছে ( আইফোনের জন্য প্রয়োজনীয়) )।

আপনি ব্যক্তিগতভাবে যদি alloc/initএকটি বস্তু, এটা 1. একটি রেফারেন্স গণনা দিয়ে আসে আপনি যখন এটি আর প্রয়োজন হচ্ছে পরে পরিষ্কার আপ জন্য দায়ী পারেন কল করে [foo release]বা[foo autorelease] । রিলিজ এখুনি এটি পরিষ্কার করে দেয়, অন্যদিকে স্বতন্ত্র প্লিজটি বস্তুটি অটোরিলিজ পুলে যুক্ত করে, যা এটি পরবর্তী সময়ে স্বয়ংক্রিয়ভাবে মুক্তি পাবে।

অটোরিলেজ মূলত যখন আপনার কোনও পদ্ধতি থাকে যা প্রশ্নে অবজেক্টটি ফেরত দিতে হয় ( সুতরাং আপনি ম্যানুয়ালি এটি প্রকাশ করতে পারবেন না, অন্যথায় আপনি কোনও শূন্য বস্তু ফিরে পাবেন) তবে আপনি ) তবে আপনি এটি ধরে রাখতে চান না, হয় ।

আপনি যদি এমন কোনও জিনিস অর্জন করেন যেখানে এটি পাওয়ার জন্য আপনি বরাদ্দ / আরআর কল করেননি - উদাহরণস্বরূপ:

foo = [NSString stringWithString:@"hello"];

তবে আপনি এই অবজেক্টটিতে ঝুলতে চান, আপনাকে [foo ধরে রাখুন] কল করতে হবে। অন্যথায়, এটি সম্ভব হবে autoreleasedএবং আপনি একটি শূন্য রেফারেন্স ধরে রাখবেন (এটি উপরের stringWithStringউদাহরণে যেমন হবে )। যখন আপনার আর প্রয়োজন নেই, কল করুন [foo release]


2

উপরের উত্তরগুলি ডকুমেন্টেশন যা বলে তার স্পষ্ট পুনঃস্থাপন দেয়; বেশিরভাগ নতুন লোকেরা যে সমস্যায় পড়েছেন তা হ'ল অননুমোদিত ঘটনা। উদাহরণ স্বরূপ:

  • অটোরিলেজ : ডক্স বলছে এটি "ভবিষ্যতের কোনও সময়ে" একটি রিলিজ ট্রিগার করবে। কখন?! মূলত, আপনি আপনার ইভেন্টটি সিস্টেম ইভেন্ট লুপে ফিরে বের না হওয়া অবধি অবজেক্টের আশেপাশে থাকতে পারবেন। সিস্টেম বর্তমান ইভেন্ট চক্রের পরে যেকোন সময় অবজেক্টটি প্রকাশ করতে পারে। (আমার মনে হয় ম্যাট এটা আগে বলেছিল)

  • স্ট্যাটিক স্ট্রিংস : NSString *foo = @"bar";- আপনাকে কী ধরে রাখতে হবে বা ছেড়ে দিতে হবে? না। কিভাবে

    -(void)getBar {
        return @"bar";
    }

    ...

    NSString *foo = [self getBar]; // still no need to retain or release
  • সৃষ্টির নিয়ম : আপনি যদি এটি তৈরি করেন তবে এটি আপনার মালিকানাধীন এবং আশা করা হচ্ছে এটি প্রকাশিত হবে।

সাধারণভাবে, নতুন কোকো প্রোগ্রামাররা যেভাবে গোলমাল হবেন তা হ'ল কোন রুটিনগুলি একটি দিয়ে কোন বস্তুকে প্রত্যাবর্তন করে তা না বুঝে retainCount > 0

এখানে কোকোতে মেমরি পরিচালনার জন্য খুব সাধারণ নিয়মের একটি স্নিপেট রয়েছে :

ধারণের গণনার বিধি

  • প্রদত্ত ব্লকের মধ্যে, -কপি, -লোক এবং -রেনেটের ব্যবহার-রিলেজ এবং -অটোরিলেজের সমান হওয়া উচিত।
  • সুবিধাযুক্ত কনস্ট্রাক্টর (যেমন এনএসএসস্ট্রিংয়ের স্ট্রিংউইথ স্ট্রিং) ব্যবহার করে তৈরি করা বিষয়গুলি স্বতঃস্ফুর্ত মনে করা হয়।
  • নিজের মালিকানাধীন উদাহরণগুলি ছেড়ে দেওয়ার জন্য একটি -ডেলোক পদ্ধতি প্রয়োগ করুন

1 ম বুলেটটি বলে: আপনি যদি কল alloc(বা new fooCopy) করেন, আপনাকে সেই অবজেক্টে রিলিজ কল করতে হবে।

২ য় বুলেটটি বলে: আপনি যদি কোনও সুবিধাযুক্ত নির্মাণকারীর ব্যবহার করেন এবং আপনার চারপাশে ঝুলতে অবজেক্টের প্রয়োজন হয় (যেমন একটি চিত্র পরে আঁকতে হবে) তবে আপনাকে এটি ধরে রাখতে হবে (এবং তারপরে পরে প্রকাশ করা হবে)।

3 য় স্ব-ব্যাখ্যামূলক হওয়া উচিত।


"অটোরিলেজ: ডক্স বলছে এটি ভবিষ্যতে কোনও সময়ে" একটি রিলিজ ট্রিগার করবে WH "কখন ?!" এই দস্তাবেজটিতে ডক্সগুলি স্পষ্ট: "অটোরিলেজ মানে কেবল" পরে একটি রিলিজ বার্তা প্রেরণ করুন "(পরে কিছু সংজ্ঞার জন্য -" স্বতঃপরে পুলগুলি দেখুন ")" " অটোরিলেজ পুল স্ট্যাকের উপর নির্ভর করে যখন ...
ম্যামাল্যাক

... "সিস্টেম বর্তমান ইভেন্ট চক্রের পরে যেকোন সময় অবজেক্টটি প্রকাশ করতে পারে" " এটি সিস্টেমকে শব্দটির চেয়ে কম
ডিটেস্টিমেন্টিক করে

... এনএসএসস্ট্রিং foo = [স্ব get get বার]; // এখনও ধরে রাখা বা ছেড়ে দেওয়ার দরকার নেই এটি ভুল। যে কেউ getBar কে অনুরোধ করে সেগুলি প্রয়োগের বিশদটি জানে না, সুতরাং * তারা যদি বর্তমান সুযোগের বাইরে এটি ব্যবহার করতে চায় তবে * ধরে রাখতে হবে / প্রকাশ করতে হবে (সাধারণত অ্যাক্সেসরদের মাধ্যমে)।
ম্যামল্যাক

"কোকোতে মেমোরি ম্যানেজমেন্টের জন্য খুব সহজ নিয়ম" নিবন্ধটি বেশ কয়েকটি ক্ষেত্রে পুরানো - বিশেষত "সুবিধাযুক্ত কনস্ট্রাক্টর (যেমন এনএসএসস্ট্রিংয়ের স্ট্রিংউইথ স্ট্রিং) ব্যবহার করে তৈরি করা বিষয়গুলি স্বতঃসংশ্লিষ্ট বলে বিবেচিত হয়।" সঠিক নয় - এটি কেবল "প্রাপকের মালিকানাধীন নয়"।
এমএমএলসি


0

বেশ কয়েকটি ব্যক্তি ইতিমধ্যে উল্লিখিত হিসাবে, মেমরি ম্যানেজমেন্ট ম্যানেজমেন্ট অ্যাপল এর অন্তর্ এখন পর্যন্ত সবচেয়ে ভাল জায়গা।

একটি দরকারী লিঙ্ক যা আমি এখনও উল্লেখ করি নি তা হ'ল প্রাকটিকাল মেমরি ম্যানেজমেন্ট । আপনি যদি এগুলি অ্যাপল এর ডক্সের মাধ্যমে পড়ে থাকেন তবে আপনি এটি খুঁজে পেতে পারেন তবে এটি সরাসরি সংযোগের পক্ষে মূল্যবান। এটি উদাহরণ এবং সাধারণ ভুল সহ মেমরি পরিচালনার নিয়মের একটি উজ্জ্বল নির্বাহী সংক্ষিপ্তসার (মূলত এখানে অন্যান্য উত্তরগুলি ব্যাখ্যা করার চেষ্টা করছে, তবে তাও নয়)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.