এআরসি-র সাথে এখনও কেন অটোরেলেজপুলের প্রয়োজন?


191

এআরসি (অটোমেটিক রেফারেন্স কাউন্টিং) সহ বেশিরভাগ অংশের জন্য, আমাদের উদ্দেশ্য-সি বস্তুগুলির সাথে মেমরি পরিচালনা সম্পর্কে মোটেই ভাবার দরকার নেই। এটি NSAutoreleasePoolআর তৈরি করার অনুমতি নেই, তবে একটি নতুন বাক্য গঠন রয়েছে:

@autoreleasepool {
    
}

আমার প্রশ্ন হ'ল, আমাকে যখন ম্যানুয়ালি প্রকাশ / স্বাবলম্বীকরণ করার কথা মনে করা হচ্ছে না তখন কেন আমার এই প্রয়োজন হবে?


সম্পাদনা: আমি সমস্ত উত্তর এবং মন্তব্যগুলি সংক্ষিপ্তভাবে কী পেয়েছি তা সংক্ষিপ্ত করতে:

নতুন সিনট্যাক্স:

@autoreleasepool { … } এর জন্য নতুন সিনট্যাক্স

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

[pool drain];

অধিক গুরুত্বের সাথে:

  • এআরসি autoreleaseপাশাপাশি ব্যবহার করে release
  • এটি করার জন্য এটির জন্য একটি অটো রিলিজ পুল প্রয়োজন।
  • আরসি আপনার জন্য অটো রিলিজ পুল তৈরি করে না। যাহোক:
    • প্রতিটি কোকো অ্যাপ্লিকেশনের মূল থ্রেডটিতে ইতিমধ্যে একটি অটোরিলেজ পুল রয়েছে।
  • দুটি অনুষ্ঠান যখন আপনি ব্যবহার করতে চাইতে পারেন @autoreleasepool:
    1. যখন আপনি একটি দ্বিতীয় থ্রেডে থাকেন এবং কোনও অটো রিলিজ পুল নেই, তখন ফাঁসগুলি রোধ করতে আপনাকে নিজের তৈরি করতে হবে, যেমন myRunLoop(…) { @autoreleasepool { … } return success; }
    2. যখন আপনি আরও একটি স্থানীয় পুল তৈরি করতে চান, যেমন @ মাত্তজাগালোয় তার উত্তরে দেখিয়েছে।

1
তৃতীয় একটি অনুষ্ঠানও রয়েছে: আপনি যখন এমন কিছু বিকাশ করেন যা ইউআইকিট বা এনএসফাউন্ডেশনের সাথে সম্পর্কিত নয়। এমন কিছু যা কমান্ড লাইন সরঞ্জামগুলি ব্যবহার করে বা তাই
গারনিক

উত্তর:


214

এআরসি ধরে রাখে, রিলিজ করে এবং অটোরিলেস থেকে মুক্তি পায় না, এটি কেবল আপনার জন্য প্রয়োজনীয়গুলি যুক্ত করে। সুতরাং এখনও ধরে রাখতে কল রয়েছে, রিলিজ করার জন্য এখনও কল রয়েছে, অটোরেলেজে এখনও কল রয়েছে এবং এখনও অটো রিলিজ পুল রয়েছে।

নতুন ক্ল্যাং ৩.০ সংকলক এবং এআরসির সাথে তারা যে অন্যান্য পরিবর্তন করেছে তার মধ্যে একটি হ'ল তারা সংকলক নির্দেশিকার NSAutoReleasePoolসাথে প্রতিস্থাপন করেছে @autoreleasepoolNSAutoReleasePoolযাইহোক যাইহোক সর্বদা একটি বিশেষ "বস্তু" ছিল এবং তারা এটি তৈরি করেছিল যাতে একটি ব্যবহারের বাক্য গঠনটি কোনও বস্তুর সাথে বিভ্রান্ত না হয় যাতে এটি সাধারণত কিছুটা সহজ a

সুতরাং মূলত, আপনার প্রয়োজন @autoreleasepoolকারণ উদ্বেগের জন্য এখনও অটো রিলিজ পুল রয়েছে। আপনাকে কেবল autoreleaseকলগুলি যুক্ত করার বিষয়ে চিন্তা করার দরকার নেই ।

একটি অটো রিলিজ পুল ব্যবহার করার একটি উদাহরণ:

- (void)useALoadOfNumbers {
    for (int j = 0; j < 10000; ++j) {
        @autoreleasepool {
            for (int i = 0; i < 10000; ++i) {
                NSNumber *number = [NSNumber numberWithInt:(i+j)];
                NSLog(@"number = %p", number);
            }
        }
    }
}

একটি অতিশয় কল্পিত উদাহরণ, নিশ্চিত করুন, কিন্তু আপনি যদি না @autoreleasepoolবাইরের ভিতরে for-loop তারপর আপনি পরে 10000 100000000 বস্তু মুক্তি বদলে প্রতিটি সময় বৃত্তাকার বাইরের হতে চাই for-loop।

আপডেট: এছাড়াও এই উত্তরটি দেখুন - https://stackoverflow.com/a/7950636/1068248 - কেন @autoreleasepoolআরসি-র সাথে কিছুই করার নেই।

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


11
এটি ধরে রাখার হাত থেকে মুক্তি পাওয়া যায় না। এটি আপনার জন্য তাদের যুক্ত করে। রেফারেন্স গণনা এখনও চলছে, এটি কেবল স্বয়ংক্রিয়। সুতরাং স্বয়ংক্রিয় রেফারেন্স গণনা :-D।
ম্যাটজগ্লোলোয়

6
তাহলে কেন এটি @autoreleasepoolআমার জন্যও যুক্ত হয় না? যদি আমি স্বতঃস্ফুর্ত বা প্রকাশিত হয় তা নিয়ন্ত্রণ না করছি (এআরসি এটি আমার জন্য করে) তবে কীভাবে আমাকে জানতে হবে কখন অটোরিলিজ পুল স্থাপন করা যায়?
এম কে 12

5
আপনার অটো রিলিজ পুলগুলি কোথায় যায় তার উপর আপনার নিয়ন্ত্রণ রয়েছে। ডিফল্টরূপে আপনার পুরো অ্যাপটির চারপাশে একটি মোড়ানো রয়েছে তবে আপনি আরও চাইবেন want
ম্যাটজগ্লোলোয়

5
ভাল প্রশ্ন. আপনাকে শুধু "জানতে" হবে। একজনকে একটি জিসি ভাষায় যুক্ত করার কথা ভাবুন কেন, একজন জিসি ভাষায়, কোনও আবর্জনা সংগ্রাহককে এগিয়ে যেতে এবং এখন সংগ্রহের চক্র চালানোর জন্য কোনও ইঙ্গিত যুক্ত করতে পারে। হতে পারে আপনি জানেন যে টন অবজেক্টগুলি সাফ হয়ে যাওয়ার জন্য প্রস্তুত রয়েছে, আপনার কাছে একটি লুপ রয়েছে যা একটি গুচ্ছ টেম্পেক্ট অবজেক্টগুলিকে বরাদ্দ করে, তাই আপনি "জানেন" (বা ইনস্ট্রুমেন্টস আপনাকে বলতে পারে :) লুপের চারপাশে একটি রিলিজ পুল যুক্ত করা হবে ভাল ধারণা.
গ্রাহাম পার্কস 21

6
লুপিং উদাহরণটি অটোরিলেজ ব্যতীত পুরোপুরি সূক্ষ্মভাবে কাজ করে: যখন ভেরিয়েবল সুযোগের বাইরে চলে যায় তখন প্রতিটি বস্তু deallocated হয়। কোডটি অটোরেলিজ ছাড়াই চালানো অবিচ্ছিন্ন পরিমাণে মেমরি নেয় এবং পয়েন্টারগুলিকে পুনরায় ব্যবহার করা হচ্ছে দেখায় এবং অবজেক্টের ডেলোকের উপর ব্রেকপয়েন্ট স্থাপন করে দেখানো হয় যে লুপের মাধ্যমে প্রতিবার একবার এটি ডাকা হচ্ছে, যখন obc_storeStrong বলা হয়। হয়তো ওএসএক্স এখানে বোবা কিছু করে, কিন্তু অটোরেলেজপুল আইওএসে সম্পূর্ণ অপ্রয়োজনীয়।
গ্লেন মেইনার্ড 21

16

@autoreleasepoolকিছুই অটোরেলিজ করে না এটি একটি অটোরিলেজ পুল তৈরি করে, যাতে ব্লকের সমাপ্তি পৌঁছে গেলে, ব্লকটি সক্রিয় থাকাকালীন যে কোনও অবজেক্ট এআরসি দ্বারা স্বতঃপ্রকাশিত হয়েছিল সেগুলি রিলিজ বার্তাগুলি প্রেরণ করা হবে। অ্যাপলের অ্যাডভান্সড মেমরি ম্যানেজমেন্ট প্রোগ্রামিং গাইড এটিকে এভাবে ব্যাখ্যা করে:

অটোরিলেজ পুল ব্লকের শেষে, ব্লকের মধ্যে অটোরিলেজ বার্তা প্রাপ্ত বস্তুগুলিকে একটি রিলিজ বার্তা প্রেরণ করা হয় — অবজেক্টটি প্রতিবারের জন্য একটি রিলিজ বার্তা গ্রহণ করে যখন এটি ব্লকের মধ্যে একটি অটোরিলেজ বার্তা প্রেরণ করা হয়।


1
অগত্যা। অবজেক্টটি একটি releaseবার্তা গ্রহণ করবে তবে যদি ধরে রাখা গণনা> 1 হয় তবে অবজেক্টটি বিশিষ্ট হবে না।
andybons

@ অ্যান্ডবোনস: আপডেট হয়েছে; ধন্যবাদ। এটি কি প্রাক-এআরসি আচরণ থেকে পরিবর্তন?
outis

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

7

লোকেরা প্রায়শই কোনও ধরণের আবর্জনা সংগ্রহ বা এর মতো জন্য এআরসিটিকে ভুল বুঝে। সত্যটি হ'ল, কিছু সময়ের পরে অ্যাপল (এলএলভিএম এবং ঝনঝন প্রকল্পের জন্য ধন্যবাদ) লোকেরা বুঝতে পেরেছিল যে সংকলনের সময় অবজেক্টিভ-সি এর মেমরি প্রশাসন (সমস্ত retainsএবং অন্যান্য releases) পুরোপুরি স্বয়ংক্রিয়ায়িত হতে পারে । এটি কেবল কোড পড়ে, এটি চালানোর আগেই! :)

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

এআরসি এর এ সংকলন সময়ে স্বয়ংক্রিয়, যা আবর্জনা সংগ্রহের মতো রান সময়ের চেয়ে অনেক ভাল।

আমাদের এখনও রয়েছে @autoreleasepool{...}কারণ এটি থাকার ফলে কোনও নিয়ম ভঙ্গ হয় না, আমরা যখনই আমাদের প্রয়োজনবোধ করি আমাদের পুল তৈরি / নিকাশ করি free


1
এআরসি হ'ল জিসি গণনা করা হচ্ছে, আপনি জাভাস্ক্রিপ্ট এবং জাভাতে পেয়ে যাচ্ছেন এমন মার্ক-অ্যান্ড-সুইপ জিসি নয়, তবে এটি অবশ্যই আবর্জনা সংগ্রহ। এটি প্রশ্নের সমাধান করে না - "আপনি করতে" কেন "আপনার উচিত" এর প্রশ্নের উত্তর দেয় না। আপনার উচিত হবে না।
গ্লেন মেইনার্ড 21

3

এটি কারণ কারণ এখনও স্বাবলম্বিত বস্তুর সুযোগের বাইরে যাওয়ার জন্য কখন নিরাপদ সে সম্পর্কে আপনাকে ইঙ্গিতগুলির সাথে সংকলক সরবরাহ করতে হবে।


আপনার কখন এটি করার দরকার হবে তার একটি উদাহরণ দিতে পারেন?
এম কে 12


সুতরাং এআরসি-র আগে, উদাহরণস্বরূপ, আমার ওপেনজিএল অ্যাপ্লিকেশনটির জন্য আমার একটি সিভিডি ডিসপ্লেলিংক একটি গৌণ থ্রেডে চলছিল, তবে আমি এর রানলুপে একটি অটোরলেজ পুল তৈরি করিনি কারণ আমি জানতাম যে আমি কোনও কিছুই অটোরিলেসিং করছি না (বা যা গ্রন্থাগার ব্যবহার করে) using এর অর্থ কি এখন আমার যুক্ত করা দরকার @autoreleasepoolকারণ আমি জানি না যে এআরসি কোনও কিছুর স্বতঃসংশোধনের সিদ্ধান্ত নিতে পারে কিনা?
এম কে 12

@ এম কে 12 - না। আপনার কাছে এখনও সর্বদা একটি অটো রিলিজ পুল থাকবে যা প্রতিবার মূল রান লুপের চারদিকে জমে। আপনার কেবল তখন একটি যুক্ত করা উচিত যখন আপনি নিশ্চিত করতে চান যে স্বতঃপ্রকাশিত বস্তুগুলি অন্যথায় যাবার আগে সেগুলি শুকিয়ে যাবে - উদাহরণস্বরূপ, পরের বার রান লুপের চারপাশে।
ম্যাটজগ্লোলোয়

2
@ ডগডাব্লু - সংকলকটি আসলে কী করছে এবং আমি এখানে এটি সম্পর্কে ব্লগ করেছি - আইফোন.গলওয়ে.মে.ইউক / ২ / ২ / এ-ভিউ-আন্ডার-কারসস-হুড- ep -পর্ব -3 /। আশা করি সংকলন-সময় এবং রান-টাইম উভয় যা চলছে তা ব্যাখ্যা করুন।
ম্যাটজগ্লোলোয়

2

Https://developer.apple.com/library/mac/docamentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html থেকে উদ্ধৃত :

অটোরলেজ পুল ব্লক এবং থ্রেডস

একটি কোকো অ্যাপ্লিকেশনের প্রতিটি থ্রেড তার নিজস্ব স্টোরটি পোল ব্লকগুলিতে বজায় রাখে। আপনি যদি কেবলমাত্র একটি ফাউন্ডেশন-প্রোগ্রাম লিখছেন বা আপনি যদি কোনও থ্রেড বিযুক্ত করেন, আপনার নিজের অটোরিলেজ পুল ব্লক তৈরি করতে হবে।

যদি আপনার অ্যাপ্লিকেশন বা থ্রেড দীর্ঘস্থায়ী হয় এবং সম্ভাব্যভাবে প্রচুর পরিমাণে অটোরিলেজড অবজেক্ট উত্পন্ন করে থাকে তবে আপনার অটোরিলিজ পুল ব্লকগুলি ব্যবহার করা উচিত (যেমন অ্যাপকিট এবং ইউআইকিট মূল থ্রেডে করেন); অন্যথায়, স্বতঃস্ফূর্ত বিষয়গুলি জমে এবং আপনার মেমরির পদচিহ্ন বৃদ্ধি পায়। যদি আপনার বিচ্ছিন্ন থ্রেড কোকো কল না করে তবে আপনাকে অটোরিলেজ পুল ব্লক ব্যবহার করার দরকার নেই।

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

...

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


2

একটি পদ্ধতি থেকে নতুন তৈরি করা অবজেক্ট ফেরত দেওয়ার জন্য অটোরলেজ পুলগুলির প্রয়োজন। যেমন কোড এই টুকরা বিবেচনা:

- (NSString *)messageOfTheDay {
    return [[NSString alloc] initWithFormat:@"Hello %@!", self.username];
}

পদ্ধতিতে তৈরি স্ট্রিংটির একটির একটি ধরে রাখা গণনা থাকবে। এখন কে মুক্তির সাথে এই গণনা বজায় রাখবে?

পদ্ধতি নিজেই? সম্ভব নয়, এটি তৈরি করা বস্তুটি ফিরিয়ে দিতে হবে, সুতরাং এটি ফিরে আসার আগে এটি প্রকাশ করা উচিত নয়।

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

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

এজন্য সেখানে অটোরিলেজ পুল রয়েছে, সুতরাং প্রথম পদ্ধতিটি বাস্তবে পরিণত হবে

- (NSString *)messageOfTheDay {
    NSString * res = [[NSString alloc] initWithFormat:@"Hello %@!", self.username];
    return [res autorelease];
}

autoreleaseকোনও বস্তুতে কল করা এটি অটোরিলিজ পুলে যুক্ত করে, তবে এর অর্থ কী? ঠিক আছে, এটির অর্থ আপনার সিস্টেমকে বলার অর্থ " আমি চাই যে আপনি আমার জন্য সেই বস্তুটি মুক্তি দিন তবে পরবর্তী সময়ে এখন নয়; এটির একটি পুনরুদ্ধার দ্বারা ভারসাম্য বজায় রাখা দরকার অন্যথায় স্মৃতি ফাঁস হবে তবে আমি নিজেই এটি করতে পারি না এই মুহুর্তে, যেহেতু আমার বর্তমান সুযোগ ছাড়িয়ে বেঁচে থাকার জন্য আমার প্রয়োজন হবে এবং আমার কলকারী আমার পক্ষে এটিও করবে না, এটি করার দরকার নেই এর কোনও জ্ঞান নেই So সুতরাং এটি আপনার পুলটিতে যুক্ত করুন এবং একবার আপনি এটি পরিষ্কার করে ফেলুন once পুল, আমার জন্য আমার উদ্দেশ্য পরিষ্কার করুন। "

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

এই আরসি কোডটি বিবেচনা করুন:

// Callee
- (SomeObject *)getSomeObject {
    return [[SomeObject alloc] init];
}

// Caller
SomeObject * obj = [self getSomeObject];
[obj doStuff];

সিস্টেমটি যে কোডটি উত্পন্ন করে, তা নিম্নলিখিত কোডগুলির মতো আচরণ করতে পারে (এটি নিরাপদ সংস্করণ যা আপনাকে নিখরচায় এআরসি এবং নন-এআরসি কোডের মিশ্রণ করতে দেয়):

// Callee
- (SomeObject *)getSomeObject {
    return [[[SomeObject alloc] init] autorelease];
}

// Caller
SomeObject * obj = [[self getSomeObject] retain];
[obj doStuff];
[obj release];

(কলারে থাকা রক্ষণ / রিলিজটি কেবল একটি প্রতিরক্ষামূলক সুরক্ষা বজায় রাখা দরকার, এটি কঠোরভাবে প্রয়োজন হয় না, কোডটি ছাড়াই পুরোপুরি সঠিক হবে)

বা এটি রান কোডের সময় এআরসি ব্যবহার করার জন্য উভয়কেই সনাক্ত করা যায় সে ক্ষেত্রে এটি এই কোডটির মতো আচরণ করতে পারে:

// Callee
- (SomeObject *)getSomeObject {
    return [[SomeObject alloc] init];
}

// Caller
SomeObject * obj = [self getSomeObject];
[obj doStuff];
[obj release];

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

এখন আসল প্রশ্ন: কেন একটি ব্যবহার করবে @autoreleasepool ?

বেশিরভাগ বিকাশকারীদের জন্য, এই কোডটি তাদের কোডটিতে ব্যবহারের জন্য কেবল একটি কারণ বাকি আছে এবং তা হল প্রযোজ্য যেখানে মেমরির পদচিহ্নগুলি ছোট রাখা। যেমন এই লুপ বিবেচনা:

for (int i = 0; i < 1000000; i++) {
    // ... code ...
    TempObject * to = [TempObject tempObjectForData:...];
    // ... do something with to ...
}

ধরে নিন যে প্রতিটি কল tempObjectForDataএকটি নতুন তৈরি করতে পারেTempObject কলই যা স্বতঃপ্রণোদিতভাবে ফিরে আসে। লুপটি এই টেম্পোর অবজেক্টগুলির এক মিলিয়ন তৈরি করবে যা সমস্ত বর্তমান অটোরিলেপপুলে সংগ্রহ করা হয় এবং কেবল একবার পুলটি ধ্বংস হয়ে গেলে সমস্ত টেম্পের অবজেক্টগুলিও ধ্বংস হয়ে যায়। যতক্ষণ না ঘটে ততক্ষণ আপনার কাছে মেমরির মধ্যে এই এক মিলিয়ন টেম্পের জিনিস রয়েছে।

আপনি যদি এর পরিবর্তে কোডটি লিখেন:

for (int i = 0; i < 1000000; i++) @autoreleasepool {
    // ... code ...
    TempObject * to = [TempObject tempObjectForData:...];
    // ... do something with to ...
}

তারপরে ফর-লুপটি চলার সময় একটি নতুন পুল তৈরি হয় এবং প্রতিটি লুপ পুনরাবৃত্তির শেষে ধ্বংস হয়। লুপটি দশ মিলিয়ন বার চালানো সত্ত্বেও সর্বাধিক একটি টেম্পের অবজেক্ট যেকোন সময় স্মৃতিতে ঝুলতে থাকে।

অতীতে, থ্রেডগুলি পরিচালনা করার সময় নিজেকে প্রায়শই অটোরিলেজপুলগুলি পরিচালনা করতে হত (যেমন ব্যবহার করা NSThread) কেবল মূল থ্রেডে স্বয়ংক্রিয়ভাবে একটি কোকো / ইউআইকিট অ্যাপ্লিকেশনটির জন্য একটি অটোরিলেজ পুল রয়েছে। তবুও এটি আজ অনেক উত্তরাধিকার হিসাবে সম্ভবত আপনি শুরু করতে থ্রেড ব্যবহার করবেন না। আপনি জিসিডি DispatchQueueবা এর ব্যবহার করতেন NSOperationQueueএবং এই দু'টিই আপনার জন্য একটি শীর্ষ স্তরের অটোরলেজ পুল পরিচালনা করে যা একটি ব্লক / টাস্ক চালানোর আগে তৈরি হয়েছিল এবং এটির সাথে একবার হয়ে গেলে এটি ধ্বংস হয়ে যায়।


-4

এই বিষয়টিকে নিয়ে অনেক বিভ্রান্তি রয়েছে বলে মনে হয় (এবং কমপক্ষে ৮০ জন যারা সম্ভবত এটি সম্পর্কে বিভ্রান্ত রয়েছেন এবং তারা তাদের কোডের চারপাশে @ অটোরেলেজপুল ছিটানো দরকার বলে মনে করেন)।

যদি কোনও প্রকল্প (তার নির্ভরতা সহ) একচেটিয়াভাবে আরসি ব্যবহার করে তবে @autoreleasepool কখনও ব্যবহার করার প্রয়োজন হয় না এবং কার্যকর কিছু করতে হবে না। এআরসি সঠিক সময়ে রিলিজিং অবজেক্টগুলি পরিচালনা করবে। উদাহরণ স্বরূপ:

@interface Testing: NSObject
+ (void) test;
@end

@implementation Testing
- (void) dealloc { NSLog(@"dealloc"); }

+ (void) test
{
    while(true) NSLog(@"p = %p", [Testing new]);
}
@end

প্রদর্শন:

p = 0x17696f80
dealloc
p = 0x17570a90
dealloc

প্রতিটি টেস্টিং অবজেক্ট অটোরিলেজ পুলটি বেরিয়ে আসার অপেক্ষা না করেই মানটি সুযোগের বাইরে চলে যাওয়ার সাথে সাথেই তা বিচ্ছিন্ন হয়ে যায়। (NSNumber উদাহরণের সাথে একই জিনিস ঘটে; এটি আমাদের কেবল ডেলোকটি পর্যবেক্ষণ করতে দেয়)) আরসি অটোরিলেজ ব্যবহার করে না।

@ অটোরেলেজপুল এখনও অনুমোদিত হওয়ার কারণটি হল মিশ্র এআরসি এবং নন-এআরসি প্রকল্পগুলির জন্য, যা এখনও পুরোপুরি এআরসিতে স্থানান্তরিত হয়নি।

আপনি যদি নন-আরসি কোডে কল করেন তবে এটি it একটি স্বতঃপ্রযুক্ত বস্তুটি ফিরিয়ে পারে। সেক্ষেত্রে উপরের লুপটি ফাঁস হবে, যেহেতু বর্তমান অটোরলেজ পুলটি কখনই বাইরে বের হবে না। আপনি এখানে কোড ব্লকের চারপাশে একটি @utoreleasepool রাখতে চান।

তবে আপনি যদি পুরোপুরি এআরসি স্থানান্তর করে ফেলেছেন তবে অটোরেলেজপুলটি ভুলে যান।


4
এই উত্তরটি ভুল এবং এটিআরসি ডকুমেন্টেশনের বিরুদ্ধেও যায়। আপনার প্রমাণগুলি হ'ল বিবরণী কারণ আপনি এমন একটি বরাদ্দ পদ্ধতি ব্যবহার করছেন যা সংকলকটি স্বতঃপরিচয় না দেওয়ার সিদ্ধান্ত নেয়। আপনি যদি নিজের কাস্টম ক্লাসের জন্য একটি নতুন স্ট্যাটিক ইনিশিয়ালাইজার তৈরি করেন তবে আপনি খুব সহজেই এটি কাজ করছে না তা দেখতে পাচ্ছেন। এই সূচনাকারী তৈরি করুন এবং আপনার লুপ এটি ব্যবহার: + (Testing *) testing { return [Testing new] }। তারপরে আপনি দেখতে পাবেন যে ডেললকটি পরবর্তীকালে কল করা হবে না। যদি আপনি কোনও @autoreleasepoolব্লকে লুপটির অভ্যন্তর মোড়ন করেন তবে এটি স্থির করা হয়েছে ।
দিমা

@ ডিমা আইওএস ১০-তে চেষ্টা করেছেন, অবজেক্টের ঠিকানা ছাপানোর সাথে সাথে ডেলোক কল করুন called + (Testing *) testing { return [Testing new];} + (void) test { while(true) NSLog(@"p = %p", [self testing]);}
কুডোসিসি

@ কুডোসিসি - আমিও তাই করেছিলাম এবং আমিও আপনার মতো আচরণ দেখেছি। কিন্তু, যখন আমি [UIImage imageWithData]সমীকরণটি ছুঁড়ে ফেলি , তখন হঠাৎ করেই আমি প্রচলিত autoreleaseআচরণ দেখতে শুরু করি , @autoreleasepoolশিখর স্মৃতিটিকে কিছুটা যুক্তিসঙ্গত পর্যায়ে রাখতে হবে।
রব

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