অবজেক্টিভ-সিতে আমি কেন স্ব = [সুপার থিম] শূন্য নয় তা পরীক্ষা করব?


165

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

আমি এটি সর্বত্র দেখতে পেয়েছি (অ্যাপলের কোড, বই, ওপেন সোর্স কোড ইত্যাদি) যে কোনও init পদ্ধতিতে পরীক্ষা করা উচিত যদি সূচনাটি চালিয়ে যাওয়ার আগে স্ব = [সুপার থ্রি] নিরুক্ত না হয়।

কোনও init পদ্ধতির জন্য ডিফল্ট অ্যাপল টেম্পলেটটি হ'ল:

- (id) init
{
    self = [super init];

    if (self != nil)
    {
        // your code here
    }

    return self;
}

কেন?

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

এটি কি সাধারণ যে কোনও ক্লাসের 'ডিআইডি পদ্ধতি শূন্য হতে পারে? যদি তা হয় তবে কোন ক্ষেত্রে এবং কেন?


1
উইল শিপলি কিছুক্ষণ আগে এই সম্পর্কিত একটি নিবন্ধ পোস্ট করেছিলেন। [স্ব = [ মূ init ় দীক্ষা ];] ( উইলশিলে . com / blog / 2005 / 07/ self-stupid- init.html ) মন্তব্যগুলি পড়ুন, কিছু ভাল জিনিস।
রায়ান টাউনশ্যান্ড

6
আপনি উইল শিপলি বা মাইক অ্যাশ বা ম্যাট গ্যালাগারকে জিজ্ঞাসা করতে পারেন । যে কোনও উপায়ে এটি বিতর্কিত বিষয় something তবে সাধারণত অ্যাপলের আইডিয়ামগুলির সাথে লেগে থাকা ভাল ... এটি সর্বোপরি তাদের ফ্রেমওয়ার্ক।
jbrennan

1
দেখে মনে হচ্ছে উইল ইনডির সময় অন্ধভাবে নিজেকে পুনরায় নিয়োগ না করার জন্য আরও একটি মামলা করছিল, এই জেনে যে [সুপার থিম] রিসিভারটি ফিরিয়ে দিতে পারে না।
জাসারিয়েন

3
পোস্টটি মূলত তৈরি হওয়ার পর থেকে উইল তার চিন্তাভাবনা পরিবর্তন করেছেন।
বুবুম

5
আমি এই প্রশ্নটি কিছুক্ষণ আগে দেখেছি এবং এটি আবার খুঁজে পেয়েছি। পারফেক্ট। +1
ড্যান রোজনস্টার্ক

উত্তর:


53

উদাহরণ স্বরূপ:

[[NSData alloc] initWithContentsOfFile:@"this/path/doesn't/exist/"];
[[NSImage alloc] initWithContentsOfFile:@"unsupportedFormat.sjt"];
[NSImage imageNamed:@"AnImageThatIsntInTheImageCache"];

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


10
হ্যাঁ, তবে এটি সংশ্লিষ্ট শ্রেণীর 'আরিক পদ্ধতিতে অন্তর্ভুক্ত নয়। এনএসডাটা এনএসবজেক্ট থেকে উত্তরাধিকার সূত্রে প্রাপ্ত। এনএসডিটা কি পরীক্ষা করে [সুপার থিম] শূন্য করে? আমি এখানে যা জিজ্ঞাসা করছি। দুঃখিত যদি আমি পরিষ্কার না হত ...
জাসারিন

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

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

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

4
যদি বরাদ্দ শূন্য হয়, init শূন্যপদে প্রেরণ করা হয়, যা সর্বদা শূন্য হয়, এটি স্ব-শূন্য হওয়ার সাথে শেষ হয়।
টি।

50

এই বিশেষ প্রতিমাটি প্রমিত কারণ এটি সব ক্ষেত্রেই কাজ করে।

অস্বাভাবিক হলেও, এমন কিছু ঘটনা ঘটবে যেখানে ...

[super init];

... এইভাবে স্বতন্ত্রত্বের প্রয়োজন হয়, অন্যরকম উদাহরণ দেয়।

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

তল লাইনটি হ'ল এটি ব্যবহার করার জন্য ডকুমেন্টেড সঠিক প্যাটার্ন এবং যদি আপনি এটি ব্যবহার না করে থাকেন তবে আপনি এটি ভুল করছেন।


3
এগুলি কি নালাগেটি স্পেসিফায়ারের আলোকে সত্য? যদি আমার সুপারক্লাসের ইনিশিয়ালাইজারটি শূন্য হয় তবে এটি কি এখনও অতিরিক্ত বিশৃঙ্খলা পরীক্ষা করে দেখার মতো? (যদিও এনএসবজেক্ট নিজেই এর -initআফটিক্সের জন্য কিছু আছে বলে মনে হচ্ছে না ...)
natevw

[super init]সরাসরি সুপারক্লাস থাকাকালীন এমন কোনও মামলা রয়েছে কি NSObject? এটি কি এমন পরিস্থিতি নয় যেখানে "সবকিছু ভেঙে গেছে?"
ড্যান রোজনস্টার্ক

1
@DanRosenstark যদি না NSObjectসরাসরি সুপারক্লাস হয়। আপনি ... এমনকি যদি NSObjectসরাসরি সুপারক্লাস হিসাবে ঘোষণা করেন, রানটাইমের সময় এমন কিছু সংশোধন করা যেতে পারে যা NSObjectবাস্তবায়ন initবলা হয় না।
bbum

1
অনেক ধন্যবাদ @ বাবাম, এটি আমাকে সত্যই কিছু বাগ ফিক্সিংয়ের দিকে পরিচালিত করতে সহায়তা করেছিল। কিছু জিনিস আউট ভাল!
ড্যান রোজনস্টার্ক

26

আমি মনে করি, বেশিরভাগ ক্লাসে, যদি [সুপার থ্রি] থেকে ফেরতের মান শূন্য হয় এবং আপনি এটি স্ট্যান্ডার্ড অনুশীলনগুলির দ্বারা প্রস্তাবিত হিসাবে পরীক্ষা করে দেখেন, এবং তারপরে অকারণে ফিরে আসেন তবে মূলত আপনার অ্যাপটি এখনও সঠিকভাবে কাজ করছে না। আপনি, এটা আমার মনে হয় এমনকি যে যদিও যদি (স্ব! = শূন্য) পরীক্ষা আছে, আপনার বর্গ যথাযথ অপারেশন জন্য, সময় আপনি আসলে এর 99.99% না স্ব প্রয়োজন অ শূন্য যাবে। এখন, অনুমান, কারনের জন্য, [সুপার Init] করেনি প্রত্যাবর্তন শূন্য, মূলত শূন্য বিরুদ্ধে আপনার চেক মূলত আপনার বর্গ, এর আহ্বায়ক পর্যন্ত হরিণ ক্ষণস্থায়ী হয় যেখানে এটি সম্ভবত, কোন পথে ব্যর্থ হবে যেহেতু এটি প্রাকৃতিকভাবে অনুমান করবে কল ছিল সফল।

মূলত, আমি যা পাচ্ছি তা হল 99.99% সময়, যদি (স্ব! = শূন্য) আপনি আরও বেশি দৃust়তার দিক থেকে আপনাকে কিছু না কিনে থাকেন, যেহেতু আপনি কেবল আপনার চালকের কাছে টাকাটি প্রেরণ করছেন। সত্যিই এই দৃ rob়তার সাথে পরিচালনা করতে সক্ষম হতে আপনাকে আপনার পুরো কলিং শ্রেণিবিন্যাসে চেক লাগাতে হবে। এবং তারপরেও, এটি আপনাকে কিনে দেবে কেবলমাত্র আপনার অ্যাপ্লিকেশনটি আরও পরিষ্কার / দৃ rob়তার সাথে ব্যর্থ হবে। কিন্তু এটি এখনও ব্যর্থ হবে।

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

আমি মনে করি এটি অ্যাপ্লিকেশনগুলি আরও সীমাবদ্ধ মেমোরিতে চালিত হওয়ার পরেও কোনও উত্তরাধিকার কোডিংয়ের পরামর্শ।

তবে সি লেভেল কোডের জন্য, আমি এখনও একটি এনএলএল পয়েন্টারের বিপরীতে ম্যালোক () এর রিটার্ন মানটি পরীক্ষা করে দেখতে পারি। যদিও অবজেক্টিভ-সি এর বিপরীতে প্রমাণ না পাওয়া পর্যন্ত আমি মনে করি আমি সাধারণত যদি (স্ব! = নিল) চেকগুলি এড়িয়ে যাব। তাত্পর্য কেন?

কারণ, সি এবং ম্যালোক স্তরে কিছু ক্ষেত্রে আপনি আসলে আংশিক পুনরুদ্ধার করতে পারেন। যদিও আমি মনে করি অবজেক্টিভ সি-তে, 99.99% ক্ষেত্রে, [সুপার থ্রি] যদি শূন্য না করে, আপনি মূলত এফ *** এড করুন, এমনকি যদি আপনি এটি পরিচালনা করার চেষ্টাও করেন না। আপনি পাশাপাশি অ্যাপটিকে ক্র্যাশ করতে এবং পরিণামের সাথে ডিল করতে পারেন।


6
ভালো বলেছিলে. আমি দ্বিতীয় যে.
রজার সিএস ওয়ার্নারসন

3
+1 আমি সম্পূর্ণ একমত কেবল একটি ছোট্ট নোট: আমি বিশ্বাস করি না যে প্যাটার্নটি এমন সময় থেকে ফলাফল যেখানে বরাদ্দ প্রায়শই ব্যর্থ হয়। ডিগ্রি ডাকা হওয়ার সময় সাধারণত বরাদ্দ দেওয়া হয়। যদি বরাদ্দ ব্যর্থ হয়, init এমনকি কল করা হবে না।
নিকোলাই রুহে

8

এটি উপরের মন্তব্যের একটি সংক্ষিপ্তসার।

সুপারক্লাসের রিটার্ন বলি nil। কি ঘটবে?

আপনি যদি সম্মেলনগুলি অনুসরণ না করেন

আপনার কোডটি আপনার initপদ্ধতির মাঝখানে ক্রাশ হয়ে যাচ্ছে । (যদি initনা তাত্পর্য কিছুই না থাকে)

যদি আপনি সম্মেলনগুলি অনুসরণ করেন, না জেনেই না যে সুপারক্লাসটি শূন্য হতে পারে (বেশিরভাগ লোকেরা এখানেই শেষ হবে)

আপনার কোডটি পরে কোনও সময়ে ক্র্যাশ হয়ে উঠবে, কারণ আপনার উদাহরণটি nilযেখানে আপনি অন্যরকম কিছু প্রত্যাশা করেছিলেন। অথবা আপনার প্রোগ্রামটি ক্র্যাশ না করে অপ্রত্যাশিতভাবে আচরণ করবে। ওহে প্রিয়! তুমি কি এটা চাও? আমি জানি না ...

আপনি যদি কনভেনশনগুলি অনুসরণ করেন, স্বেচ্ছায় আপনার সাবক্লাসটি শূন্য করার সুযোগ দেয়

আপনার কোড ডকুমেন্টেশনের (!) স্পষ্টভাবে বলা উচিত: "রিটার্ন ... বা নীল", এবং আপনার কোডের বাকি অংশগুলি এটি পরিচালনা করার জন্য প্রস্তুত হওয়া প্রয়োজন। এখন এটি বোধগম্য হয়।


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

অথবা আপনি
স্যুইফ্টে

7

সাধারণত, যদি আপনার ক্লাসটি সরাসরি থেকে আসে তবে আপনার NSObjectপ্রয়োজন হবে না। যাইহোক, এটি প্রবেশ করা একটি ভাল অভ্যাস, যেমন আপনার ক্লাসটি অন্য শ্রেণি থেকে নেওয়া, তাদের আরম্ভকারীরা ফিরে আসতে পারে nilএবং যদি তাই হয় তবে আপনার আরম্ভকারীটি সেটিকে ক্যাপচার করতে এবং সঠিকভাবে আচরণ করতে পারে।

এবং হ্যাঁ, রেকর্ডের জন্য, আমি সেরা অনুশীলনটি অনুসরণ করি এবং এটি আমার সমস্ত ক্লাসে লিখি, এমনকি সরাসরি প্রাপ্ত ব্যক্তিরাও NSObject


1
এটি মাথায় রেখে, কোনও পরিবর্তনশীল সূচনা করার পরে এবং এতে ফাংশন কল করার আগে শূন্যতার জন্য পরীক্ষা করা কি ভাল অনুশীলন হবে? যেমনFoo *bar = [[Foo alloc] init]; if (bar) {[bar doStuff];}
dev_does_software

জিএন ইউস্টেপ-এর পুরানো সংস্করণগুলির মতো বহিরাগত রানটাইমগুলি গণনা করা হয় (যা প্রত্যাবর্তন করে ) তবে যাই হোক না কেন, একটি চেক এবং একটি অ্যাসাইন, এর থেকে উত্তরাধিকারী হওয়া আপনাকে NSObjectগ্যারান্টি -initদেয় না । NSObjectGSObject
ম্যাক্সথন চ্যান

3

আপনি ঠিক বলেছেন, আপনি প্রায়শই স্রেফ লিখতে পারতেন [super init]তবে এটি কোনও কিছুর সাবক্লাসের জন্য কাজ করবে না। লোকেরা কেবলমাত্র একটি স্ট্যান্ডার্ড লাইন মুখস্থ করতে এবং সর্বদা এটি ব্যবহার করতে পছন্দ করে, এমনকি যখন এটি কেবল কখনও কখনও প্রয়োজনীয় হয়, এবং এইভাবে আমরা স্ট্যান্ডার্ডটি পাই if (self = [super init])যা নীল ফিরে আসার সম্ভাবনা এবং selfপ্রত্যাবর্তন ব্যতীত অন্য কোনও বস্তুর সম্ভাবনা উভয়ই গ্রহণ করে হিসেবের মধ্যে.


3

একটি সাধারণ ভুল লিখতে হয়

self = [[super alloc] init];

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

self = [super init]; 

সুপার ক্লাসে সাবক্লাসের সদস্য স্থাপনের আগে প্রথমে আরম্ভ করার জন্য সদস্য (ভেরিয়েবল বা অন্যান্য অবজেক্ট) থাকলে প্রয়োজনীয় হয় । অন্যথায় অবজেক্ট রানটাইম এগুলিকে 0 বা শূন্য করতে শুরু করে । ( এএনএসআই সি এর বিপরীতে, যা প্রায়শই একেবারেই পরিষ্কার না করে মেমরির অংশগুলি বরাদ্দ করে )

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


2

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


এটি, তবে htey কে এক সাথে ডাকা হয়, যদি বরাদ্দ করা হয় তবে কী হবে?
ড্যানিয়েল

আমি ভাবছি যদি বরাদ্দ ব্যর্থ হয়, তবে আপনি যে ক্লাসে ডি আর কল করছেন তার উদাহরণের চেয়ে ডিআইএম শূন্য পাঠানো হবে। সেক্ষেত্রে, কিছুই ঘটবে না এবং [সুপার থিম] শূন্য হয়েছে কিনা তা পরীক্ষা করার জন্য কোনও কোড কার্যকর করা হবে না।
জাসারিন

2
মেমরি বরাদ্দ সর্বদা + বরাদ্দে করা হয় না। ক্লাস ক্লাস্টারের ক্ষেত্রে বিবেচনা করুন; কোনও এনএসএসআরং জানে না যে প্রারম্ভিকটি চালিত হওয়া অবধি কোন নির্দিষ্ট সাবক্লাসটি ব্যবহার করা উচিত।
বুবুম

1

ওএস এক্স-এ, -[NSObject init]মেমরির কারণে এটি ব্যর্থ হওয়ার সম্ভাবনা নেই । আইওএসের ক্ষেত্রেও এটি বলা যায় না।

এছাড়াও, ক্লাসটি সাবক্লাসিং করার সময় লেখার পক্ষে এটি ভাল অভ্যাস nilযা কোনও কারণেই ফিরে আসতে পারে ।


2
উভয় iOS এবং ম্যাক অপারেটিং সিস্টেম উপর -[NSObject init]হয় খুব মেমরির কারণে ব্যর্থ যেমন কোনো মেমরি বরাদ্দ নেই অসম্ভাব্য।
নিকোলাই রুহে

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