কোকো অবজেক্ট-সি ক্লাসে কোনও চলকের সামনে আন্ডারস্কোর কীভাবে কাজ করে?


157

আমি কয়েকটি আইফোনের উদাহরণ দেখেছি যে বৈশিষ্ট্যগুলি ভেরিয়েবলের সামনে একটি আন্ডারস্কোর _ ব্যবহার করেছে। এর অর্থ কী কেউ জানে? বা এটি কিভাবে কাজ করে?

একটি ইন্টারফেস ফাইল যা আমি ব্যবহার করছি তা দেখে মনে হচ্ছে:

@interface MissionCell : UITableViewCell {
    Mission *_mission;
    UILabel *_missionName;
}

@property (nonatomic, retain) UILabel *missionName;

- (Mission *)mission;

উপরের ঠিক কী করবে তা আমি নিশ্চিত নই তবে যখন আমি মিশনের নামটি সেট করার চেষ্টা করি:

aMission.missionName = missionName;

আমি ত্রুটি পেয়েছি:

কাঠামো বা ইউনিয়ন নয় এমন কিছুতে 'মিশননাম' সদস্যের জন্য অনুরোধ

উত্তর:


97

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

@synthesize missionName = _missionName;

আরও সাধারণভাবে, এটি হ'ল:

@synthesize propertyName = _ivarName;

78
স্বয়ংক্রিয় সংশ্লেষিত বৈশিষ্ট্যগুলির সাথে এটি আর প্রয়োজন হয় না। Xcode একটি @ প্রপার্টি xxxx সংশ্লেষ করে যা পর্দার আড়ালে _xxxxx নামে একটি আইভার রয়েছে। ঝরঝরে।
শিখুন কোকোস 2 ডি

@ শিখুন কোকোস 2 ডি হাই! আইওএসের এক নবাগত এবং এখানে আমার স্পষ্ট করার দরকার আছে। এই সময়ের জন্য আমি যা করেছি তা হ'ল propertyফাইলটিতে এবং .m fie এ ঘোষণা করেছিলাম, আমি এটির selfমতো ব্যবহার করে এটি অ্যাক্সেস করি self.someProperty। এটা কি সঠিক পথ? বা কোডটিতে আইভারা ব্যবহার করা উচিত?
ইসুর

আইভার সেট করা সম্পত্তি সেটারটি চালায় না - আপনি সিদ্ধান্ত নিন যে এটি প্রতিটি বিশেষ ক্ষেত্রে ভাল ধারণা কিনা তা নয়
শিখুন কোকোস

নুব প্রশ্ন: আইভারগুলি সরাসরি ব্যবহার করবেন না কেন? আইভারটি ধরে রাখার জন্য আমি কেন একটি পৃথক বর্ণ ঘোষণা করব?
অ্যালেন

1
@ অ্যালেন, যদি আমি আপনার প্রশ্নটি সঠিকভাবে বুঝতে পারি: আপনি যে পৃথক ভারটি ঘোষণা করছেন তা হ'ল প্রকৃত পরিবর্তনশীলটির জন্য একটি পয়েন্টার। এটি কয়েকটি কারণে গুরুত্বপূর্ণ (যা আমি জানি) প্রথমত, যখন আপনি কোনও ফাংশনে কোনও পয়েন্টারটি পাস করেন তখন আপনি এর মানটি নকল করছেন না। আপনি সহজেই ফাংশনটি বলছেন যেখানে ব্যবহারের জন্য মানটি পাবেন। এটি আপনার ব্যবহৃত স্মৃতিশক্তি কম রাখতে সহায়তা করে (এবং মেমরির বরাদ্দ এবং ডেলোকের ক্ষেত্রেও সহায়তা করে যা 'আবর্জনা সংগ্রহের অভাবে গুরুত্বপূর্ণ যা আপনি জাভাতে পাবেন)
ডেভিড সিগলে

18

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


19
আমি যা বুঝতে পেরেছি সেগুলি থেকে অ্যাপল পদ্ধতির নামগুলিতে আন্ডারস্কোর উপসর্গটি ব্যবহারের বিরুদ্ধে সুপারিশ করেন (তারা ব্যক্তিগত পদ্ধতিগুলির জন্য একটি কনভেনশন হিসাবে নিজেরাই সংরক্ষণ করেন), তবে উদাহরণের পরিবর্তনশীল নাম সম্পর্কে তাদের তেমন কোনও সুপারিশ নেই।
কেলান

9
@ কেলান আসলে, অ্যাপল এটি করতে উত্সাহিত করে : "সাধারণত, আপনার সরাসরি ভেরিয়েবলগুলি অ্যাক্সেস করা উচিত নয়, পরিবর্তে আপনার অ্যাকসেসর পদ্ধতিগুলি ব্যবহার করা উচিত (আপনারা সরাসরি আরআইএল এবং ডেলোক পদ্ধতিতে অ্যাক্সেস ইনস্ট্যান্স ভেরিয়েবলগুলি করতে পারেন) এটি সংকেত দিতে সহায়তা করার জন্য, উপসর্গ উদাহরণ আন্ডারস্কোর (_) সহ ভেরিয়েবলের নাম, উদাহরণস্বরূপ: imp @ বাস্তবায়ন মাইক্লাস {বোল _শোইজ টাইটেল;} "
স্মারকিতানভ 5:32

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

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

9

আমি দেখেছি শুধুমাত্র দরকারী উদ্দেশ্য স্থানীয় ভেরিয়েবল এবং সদস্য ভেরিয়েবলের মধ্যে পার্থক্য করা উপরে বর্ণিত, তবে এটি প্রয়োজনীয় কনভেনশন নয়। @ প্রপার্টিটির সাথে জুটি তৈরি করা হলে এটি সিনথেসাইজ স্টেটমেন্টগুলির ক্রমবিকাশ বৃদ্ধি করে - @synthesize missionName = _missionName;এবং সর্বত্র কুৎসিত।

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

-(void)setMyString:(NSString*)_myString
{
    myString = _myString;
}

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


এটি অন্যদিকে। ব্যক্তিগত ভেরিয়েবল আন্ডারকর্ড করা হয়। সম্পত্তি না। এবং কীট তাদের সংশ্লেষিত করে আপনি তাদের দু'জন করে।
জাস্টিন

এটি ঠিক যেমনটি আমি বর্ণনা করি ঠিক তেমনই আমি এটিকে "ব্যক্তিগত ভেরিয়েবল" পরিবর্তে "সদস্য ভেরিয়েবল" বলেছিলাম।
পিটার ডিউইউজ

সেকি! এটি সমস্যার জন্য জিজ্ঞাসা করছে… স্বয়ংক্রিয় সংশ্লেষণটি আইভার _ মাই স্ট্রিংকে তৈরি করবে যার অর্থ আপনার সেটারটি কাজ করবে না (কারণ এটি পরে পদ্ধতি প্যারামিটার থেকে আপনার আইভারটি বলতে সক্ষম হবে না)।
জিওয়ার

সঠিক, এ কারণেই আমি যখন সম্পাদনাটি স্বয়ংক্রিয় সংশ্লেষ যুক্ত করলাম তখন শেষে যুক্ত করলাম।
পিটার ডিউইউজ

5

এটি আসলে কোনও অর্থ নয়, এটি কেবল একটি সম্মেলন যা কিছু লোক স্থানীয় ভেরিয়েবল থেকে সদস্য ভেরিয়েবলকে পৃথক করতে ব্যবহার করে।

ত্রুটি হিসাবে মনে হচ্ছে, এমিশন-এর ভুল টাইপ রয়েছে। এটা কি ঘোষণা?


ইন্টিলিসেন্স সহ আইডিইতে এটি সাধারণ; এটি আপনার সদস্য / মডিউল / শ্রেণীর ভেরিয়েবলগুলি তালিকার শীর্ষে প্রদর্শন করবে। আরেকটি সাধারণ previx "m_" হয়
অগভীর নলকুপ

1
যদি এর অর্থ না হয় তবে আপনি আমার উপরের উদাহরণের মতো _missionName এবং মিশননমের মধ্যে কীভাবে পিছনে পিছনে স্যুইচ করতে পারেন? আমার ঘোষণাটি দেখে মনে হচ্ছে: মিশন * এমিশন = [[মিশন বরাদ্দ] init]; aMmission.missionName = @ "একটি মিশন";
আত্মা

1
একটি উদাহরণস্বরূপ পরিবর্তনশীল এবং অন্যটি সম্পত্তি। আপনি এমসেশন.মিশননামের মতো সিনট্যাক্স সহ উদাহরণ ভেরিয়েবলগুলি অ্যাক্সেস করতে পারবেন না কারণ সিনট্যাক্স পয়েন্টারগুলির সাথে কাজ করে না।
ছক

এছাড়াও, মনে রাখবেন যে আপনি একটি মিশন অবজেক্টটিতে পরিচালনা করার চেষ্টা করছেন তবে মিশননাম সম্পত্তি সহ আপনি যে ইন্টারফেসটি পোস্ট করেছেন সেটি হ'ল একটি মিশনসেল।
smorgan

2

এটি কেবল সংশ্লেষিত বৈশিষ্ট্যগুলির নামকরণের সম্মেলনের জন্য।

আপনি যখন .m ফাইলে ভেরিয়েবল সংশ্লেষ করেন, এক্সকোড স্বয়ংক্রিয়ভাবে আপনাকে _ পরিবর্তনশীল বুদ্ধি সরবরাহ করবে।


1

আন্ডারস্কোর থাকা কেবল নিজের আইভারগুলি সমাধান করা সম্ভব করে না সেল্ফ.মিম্বার সিনট্যাক্স ব্যবহার না করেই তবে এটি আপনার কোডটি আরও পঠনযোগ্য করে তোলে কারণ আপনি যখন জানেন যে যখন কোনও ভেরিয়েবল আইভার হয় (তার আন্ডারস্কোর উপসর্গের কারণে) বা সদস্য আর্গুমেন্ট (কোনও আন্ডারস্কোর হয় না) )।

উদাহরণ:

- (void) displayImage: (UIImage *) image {

    if (image != nil) {
        // Display the passed image...
        [_imageView setImage: image];
    } else {
        // fall back on the default image...
        [_imageView setImage: _image];
    }
}

এই উদাহরণে স্ব.আইমেজ (বা [স্ব চিত্র)] ব্যবহারের তুলনা দেখতে ভাল লাগবে। স্ব.আইমেজ ব্যবহার করা কখন ভাল এবং _ চিত্র ব্যবহার করা কখন ভাল?
বোকেকেম

2
@ বোকেম: সাধারণত আপনার ব্যবহার করা উচিত self.image, যা সম্পত্তিটি অ্যাক্সেস করে। আপনার কেবলমাত্র একবার চলচিত্রটি অ্যাক্সেস করার সময় _image, সরাসরি initপদ্ধতি এবং পদ্ধতির মধ্যে থাকা dealloc, যখন অন্য কোনও পদ্ধতি কল করা ঝুঁকিপূর্ণ হতে পারে (যেহেতু বস্তুটি অর্ধ-প্রাথমিক বা অর্ধ-বিভক্ত)।
পিটার হোসি

1

এটি স্ব। পরিবর্তনশীল নাম বনাম _ পরিবর্তনশীল নাম সম্পর্কে প্রশ্নের জন্য "মাস্টার" আইটেম বলে মনে হচ্ছে। লুপের জন্য আমাকে যা ছুঁড়েছিল তা হ'ল .হ, আমার ছিল:

...
@interface myClass : parentClass {
className *variableName;    // Note lack of _
}

@property (strong, nonatomic) className  *variableName;
...

এটি স্ব। পরিবর্তনশীল নাম এবং _variableName .m তে দুটি স্বতন্ত্র ভেরিয়েবল হিসাবে নিয়ে যায়। আমার যা দরকার ছিল তা হ'ল:

...
@interface myClass : parentClass {
className *_variableName;    // Note presence of _
}

@property (strong, nonatomic) className  *variableName;
...

তারপরে, ক্লাসে '.m, self.variableName এবং _variableName সমতুল্য।

আমি এখনও স্পষ্ট নই যে কেন অনেক উদাহরণ এখনও কাজ করে, এমনকি শক্ত এটি করা হয় না।

রশ্মি


0

আন্ডারস্কোরের পরিবর্তে আপনি স্ব-পরিবর্তনশীল নামটি ব্যবহার করতে পারেন বা ভেরিয়েবলটি আন্ডারস্কোর ছাড়াই আউটলেট ব্যবহার করতে সংশ্লেষ করতে পারেন।


2
আপনার যদি একই ক্লাসে কেবলমাত্র ভেরিয়েবলের প্রয়োজন হয় কেবল এটি। মি ফাইলের মধ্যেই ঘোষণা করুন এটি আপনাকে স্ব বা বিনা আন্ডারস্কোর ছাড়া কল করার অনুমতি দেবে
আনসাল আন্তনি

0

অন্যান্য উত্তরগুলি _variableথেকে অনুপস্থিত variableহ'ল ব্যবহারটি আপনাকে অনুমিত ইচ্ছামত টাইপ করতে এবং আইওয়ার অ্যাক্সেস করা থেকে বিরত রাখে (অনুমিত উদ্দেশ্যে) সম্পত্তি হিসাবে।

সংকলক আপনাকে self.variableবা অন্যটি ব্যবহার করতে বাধ্য করবে _variable। আন্ডারস্কোরগুলি ব্যবহার করা টাইপ করা অসম্ভব করে তোলে variableযা প্রোগ্রামার ত্রুটিগুলি হ্রাস করে।

- (void)fooMethod {

    // ERROR - "Use of undeclared identifier 'foo', did you mean '_foo'?"
    foo = @1;

    // So instead you must specifically choose to use the property or the ivar:

    // Property
    self.foo = @1;

    // Ivar
    _foo = @1;

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