উদ্দেশ্য-সি: আইডি এবং শূন্য * এর মধ্যে পার্থক্য


উত্তর:


240

void * এর অর্থ "কিছু টাইপড / অজানা বিষয়বস্তুর সাথে কিছু এলোমেলো অংশ 'মেমরির একটি রেফারেন্স"

id এর অর্থ "অজানা শ্রেণীর কিছু এলোমেলো উদ্দেশ্য-সি অবজেক্টের একটি রেফারেন্স"

অতিরিক্ত অর্থগত পার্থক্য রয়েছে:

  • কেবলমাত্র জিসি বা জিসি সমর্থিত মোডের অধীনে, সংকলক প্রকারের উল্লেখের জন্য লেখার বাধাগুলি প্রেরণ করবে idতবে প্রকারের জন্য নয় void *। কাঠামো ঘোষণা করার সময়, এটি একটি গুরুত্বপূর্ণ পার্থক্য হতে পারে। আইভারস এর মতো ঘোষণার void *_superPrivateDoNotTouch;ফলে যদি _superPrivateDoNotTouchবস্তুটি আসলে কোনও বস্তু থাকে তবে অকালাদির পুনরায় কাটা পড়বে । এটা করবেন না।

  • void *প্রকারের রেফারেন্সে কোনও পদ্ধতিতে অনুরোধ করার চেষ্টা করা একটি সংকলক সতর্কতাটিকে বাধা দেবে।

  • কোনও idধরণের পদ্ধতিতে অনুরোধ করার চেষ্টা করা কেবল তখনই সতর্ক করবে যে পদ্ধতিটি @interfaceসংকলক দ্বারা দেখানো কোনও ঘোষণাপত্রে কল করা হচ্ছে না বলে ঘোষণা করা হয়েছে ।

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

এর একটি সাধারণ এবং বৈধ ব্যবহার void *হল একটি অস্বচ্ছ ডেটা রেফারেন্স হিসাবে যা অন্য কোনও এপিআইয়ের মধ্য দিয়ে যায়।

এর sortedArrayUsingFunction: context:পদ্ধতিটি বিবেচনা করুন NSArray:

- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context;

বাছাইয়ের ফাংশনটি হিসাবে ঘোষণা করা হবে:

NSInteger mySortFunc(id left, id right, void *context) { ...; }

এই ক্ষেত্রে, NSArray নিছক যাই হোক না কেন আপনি মধ্যে পাস পাসের contextহিসাবে মাধ্যমে পদ্ধতিতে যুক্তি contextযুক্তি। এটি পয়েন্টার আকারের ডেটাগুলির একটি অস্বচ্ছ কুঁচক, যতদূর এনএসআরির সাথে সম্পর্কিত, এবং আপনি যে কোনও উদ্দেশ্যেই এটি ব্যবহার করতে মুক্ত free

ভাষায় ক্লোজার টাইপ বৈশিষ্ট্য ব্যতীত, কোনও ফাংশন সহ ডেটা হুঁককে বহন করার একমাত্র উপায় এটি। উদাহরণ; আপনি যদি MySortFunc () কে শর্তসাপেক্ষে কেস সংবেদনশীল বা সংবেদনশীল বা কেস সংবেদনশীল হিসাবে বাছাই করতে চান, তবুও থ্রেড-নিরাপদ থাকাকালীন আপনি প্রেক্ষাপটে আইস-কেস-সংবেদনশীল সূচকটি পাস করতে পারবেন, সম্ভবত পথে এবং বেরিয়ে আসার সম্ভাবনা রয়েছে।

ভঙ্গুর এবং ত্রুটির প্রবণতা, তবে একমাত্র উপায়।

ব্লকগুলি এটিকে সমাধান করে - ব্লকগুলি সি এর জন্য ক্লোজার They এগুলি ক্ল্যাং-এ উপলব্ধ http: // http://llvm.org/ এবং স্নো চিতাবাঘে বিস্তৃত ( http://developer.apple.com/library/ios/docamentation/Performance / রেফারেন্স / জিসিডি_লিবডিসপ্যাচ_সেফ / জিসিডি_লিবডিসপ্যাচ_রফ.পিডিএফ )।


অতিরিক্তভাবে, আমি নিশ্চিত যে একটি idসাড়া দেওয়ার জন্য অনুমান করা হয়েছে -retainএবং -releaseঅন্যদিকে void*কলির কাছে সম্পূর্ণ অস্বচ্ছ। আপনি কোনও স্বেচ্ছাসেবক পয়েন্টারটি পাস করতে পারবেন না -performSelector:withObject:afterDelay:(এটি অবজেক্টটি ধরে রাখে) এবং আপনি ধরে নিতে পারবেন না যে +[UIView beginAnimations:context:]প্রসঙ্গটি ধরে রাখা হবে (অ্যানিমেশন প্রতিনিধি প্রসঙ্গে তার মালিকানা বজায় রাখতে হবে; ইউআইকিট অ্যানিমেশন প্রতিনিধি ধরে রাখে)।
টিসি।

3
কোন idপ্রতিক্রিয়া জানায় সে সম্পর্কে কোনও অনুমান করা যায় না । একটি idসহজেই কোনও শ্রেণীর উদাহরণকে উল্লেখ করতে পারে যা অন্তর্নিহিত নয় NSObject। ব্যবহারিকভাবে বলতে গেলে, আপনার বক্তব্যটি সত্যিকারের বিশ্বের আচরণের সাথে সেরা মেলে; আপনি <NSObject>ফাউন্ডেশন এপিআইয়ের সাথে অ- প্রয়োগকারী ক্লাসগুলি মিশ্রিত করতে পারবেন না এবং খুব দূরে যেতে পারবেন, এটি অবশ্যই নিশ্চিত!
বুবুম

2
এখন idএবং Classপ্রকারগুলিকে এআরসি এর অধীনে ধরে রাখতে সক্ষম অবজেক্ট পয়েন্টার হিসাবে বিবেচনা করা হচ্ছে । সুতরাং অনুমানটি কমপক্ষে এআরসি-র অধীনে সত্য।
eonil

"অকাল কাটা" কী?
ব্র্যাড থমাস

1
@ ব্র্যাড থমাস যখন কোনও আবর্জনা সংগ্রহকারী প্রোগ্রামটি সম্পন্ন করার আগে মেমরি সংগ্রহ করে।
বুবুম 30'17

21

আইডি হ'ল উদ্দেশ্য সি অবজেক্টের পয়েন্টার, যেখানে শূন্য * হ'ল কোনও কিছুর পয়েন্টার।

আইডি অজানা মথগুলিকে কল করার সাথে সম্পর্কিত সতর্কতাগুলিও বন্ধ করে দেয়, উদাহরণস্বরূপ:

[(id)obj doSomethingWeirdYouveNeverHeardOf];

অজানা পদ্ধতি সম্পর্কে সাধারণ সতর্কতা দেবে না। এটি অবশ্যই রান সময়ে ব্যাতিক্রম বাড়িয়ে তুলবে যদি না আপত্তি শূন্য হয় বা সত্যই এই পদ্ধতিটি বাস্তবায়ন করে না।

প্রায়শই আপনার ব্যবহার করা উচিত NSObject*বা তার id<NSObject>পছন্দ হিসাবে id, যা অন্তত নিশ্চিত করে যে প্রত্যাবর্তিত বস্তুটি কোকো অবজেক্ট, তাই আপনি নিরাপদে এটি রক্ষণ / প্রকাশ / অটোরিলেজের মতো পদ্ধতি ব্যবহার করতে পারেন।


2
পদ্ধতি আহ্বানের জন্য, লক্ষ্যযুক্ত পদ্ধতিটি কোথাও ঘোষণা না করা হলে টাইপের (আইডি) একটি লক্ষ্য একটি সতর্কতা তৈরি করবে। সুতরাং, আপনার উদাহরণে, doSomethingWeird YouveNeverHeardOf সতর্কতা না হওয়ার জন্য কোথাও ঘোষণা করা উচিত ছিল।
বুবুম

আপনি ঠিক বলেছেন, আরও ভাল উদাহরণ স্টোরেজপোলিস জাতীয় কিছু হবে।
পিটার এন লুইস

@ পিটারএনলিউস এর Often you should use NSObject*পরিবর্তে আমি একমত নই id। নির্দিষ্ট করে NSObject*আপনি প্রকৃতপক্ষে স্পষ্ট করে বলছেন যে বস্তুটি একটি এনএসবজেক্ট। অবজেক্টে যেকোনো মেথড কলের ফলে একটি সতর্কতা দেখা দেবে, তবে যতক্ষণ না সেই বস্তুটি প্রকৃতপক্ষে পদ্ধতি কলটির প্রতিক্রিয়া জানায় ততক্ষণ কোনও রানটাইম ব্যতিক্রম হবে না। সতর্কতা স্পষ্টত বিরক্তিকর তাই idভাল। মোটা id<MKAnnotation>দাগের পরে আপনি উদাহরণস্বরূপ আরও নির্দিষ্ট করে বলতে পারেন , যা এই ক্ষেত্রে যার অর্থ যা কিছুই হোক না কেন এটি অবশ্যই এমকেএনোটেশন প্রোটোকলের সাথে খাপ খায়।
pnizzle

1
আপনি যদি <MKAnnotation> আইডি ব্যবহার করতে চলেছেন তবে আপনি ঠিক পাশাপাশি NSObject <MKAnnotation> * ব্যবহার করতে পারেন। এটি আপনাকে এমকেএনোটেশন এবং এনএসবজেক্টের যে কোনও পদ্ধতিতে (যেমন, সাধারণ এনএসওবজেক্ট মূল শ্রেণীর শ্রেণিবদ্ধের সমস্ত বস্তু) ব্যবহার করতে পারে এবং অন্য যে কোনও কিছুর জন্য একটি সতর্কতা পেতে দেয় যা কোনও সতর্কবার্তা এবং এর চেয়ে অনেক ভাল is একটি রানটাইম ক্র্যাশ।
পিটার এন লুইস

8

যদি কোনও পদ্ধতিতে রিটার্নের ধরণ থাকে তবে idআপনি যে কোনও অবজেক্টি-সি অবজেক্টটি ফিরিয়ে দিতে পারেন।

void মানে, পদ্ধতিটি কোনও কিছুই ফেরত দেবে না।

void *শুধু পয়েন্টার। আপনি যে পয়েন্টারটিতে ইঙ্গিত করেছেন ঠিকানার লিখিত সামগ্রীটি সম্পাদনা করতে পারবেন না।


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

8

idএকটি উদ্দেশ্য-সি অবজেক্টের পয়েন্টার। void *যে কোনও কিছুর পয়েন্টার । আপনি এর void *পরিবর্তে ব্যবহার করতে পারেন idতবে এটি প্রস্তাবিত নয় কারণ আপনি কোনও কিছুর জন্য সংকলক সতর্কতা কখনই পাবেন না।

তোমাকে দেখতে চাই পারে stackoverflow.com/questions/466777/whats-the-difference-between-declaring-a-variable-id-and-nsobject এবং unixjunkie.blogspot.com/2008/03/id-vs-nsobject-vs -id.html


1
বেশ না। (অকার্যকর *) টাইপ করা ভেরিয়েবলগুলি মোটেও পদ্ধতি আহরণের লক্ষ্য হতে পারে না। এটি সংকলক থেকে "সতর্কতা: অবৈধ রিসিভার টাইপ 'শূন্য *" "এর ফলস্বরূপ।
বুবুম

@ বুবুম: void *টাইপড ভেরিয়েবলগুলি অবশ্যই পদ্ধতি আহ্বানের লক্ষ্য হতে পারে - এটি একটি সতর্কতা, ত্রুটি নয়। শুধু আপনি এই কাজ করতে যে পারেন: int i = (int)@"Hello, string!";এবং আপ অনুসরণ করুন: printf("Sending to an int: '%s'\n", [i UTF8String]);। এটি একটি সতর্কতা, ত্রুটি নয় (এবং ঠিক প্রস্তাবিত নয়, বা বহনযোগ্যও নয়)। তবে আপনি কেন এই জিনিসগুলি করতে পারবেন তা সমস্ত মৌলিক সি
জন

1
দুঃখিত। আপনি সঠিক; এটি একটি সতর্কতা, ত্রুটি নয়। আমি সতর্কতাগুলিকে সর্বদা এবং সর্বত্র ত্রুটি হিসাবে গণ্য করি।
23:48

4
/// Represents an instance of a class.
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.
typedef struct objc_object *id;

উপরের কোডটি obc.h থেকে এসেছে, সুতরাং দেখে মনে হচ্ছে আইডি হ'ল অ্যাজজেক্ট_বজেক্ট স্ট্রাক্টের উদাহরণ এবং আইএসএ পয়েন্টারটি যে কোনও অবজেক্টিভ সি ক্লাস অবজেক্টের সাথে আবদ্ধ হতে পারে, যখন অকার্যকর * কেবল একটি টাইপড পয়েন্টার।


2

আমার বোধগম্যতা হল যে আইডি কোনও বস্তুর পয়েন্টার উপস্থাপন করে যখন শূন্য * সত্যিই যে কোনও কিছুতে নির্দেশ করতে পারে, যতক্ষণ আপনি এটি টাইপ করতে না চান ততক্ষণ আপনি এটি ব্যবহার করতে চান


আপনি যদি আইডিসহ কিছু অবৈধ প্রকারের (অকার্যকর *) থেকে কাস্ট করছেন তবে আপনি সম্ভবত এটি ভুল করছেন। এটি করার কারণ রয়েছে, তবে সেগুলি খুব কম, খুব দূরত্বের এবং প্রায় সবসময় ডিজাইনের ত্রুটির পরিচায়ক।
6

1
উদ্ধৃতি "এটি করার কারণ রয়েছে তবে সত্য যে এটির মধ্যে এগুলি খুব কম। এটা পরিস্থিতির উপর নির্ভর করে। তবে আমি কিছু প্রসঙ্গ প্রকাশ করে "আপনি খুব সম্ভবত এটি ভুল করছেন" এর মতো কম্বল বিবৃতি দেব না।
হাফেজ

আমি একটি কম্বল বিবৃতি দিতে হবে; মাঝখানে শূন্য * দিয়ে ভুল টাইপের জন্য কাস্টিংয়ের কারণে অনেকগুলি ত্রুটিযুক্ত ত্রুটিগুলি খুঁজে বের করতে হয়েছিল এবং ঠিক করতে হয়েছিল। একটি ব্যতিক্রম হ'ল কলব্যাক ভিত্তিক এপিআইগুলি যা একটি শূন্য * প্রসঙ্গে যুক্তি গ্রহণ করে যার চুক্তিতে বলা হয়েছে যে কলব্যাক সেটআপ করা এবং কলব্যাক গ্রহণের মধ্যে প্রসঙ্গটি অচ্ছুত থাকবে।
বুব্বু

0

ইতিমধ্যে যা বলা হয়েছে তা ছাড়াও সংগ্রহের সাথে সম্পর্কিত অবজেক্ট এবং পয়েন্টারের মধ্যে পার্থক্য রয়েছে। উদাহরণস্বরূপ, আপনি যদি এনএসআরাইতে কিছু রাখতে চান তবে আপনার একটি অবজেক্টের প্রয়োজন ("আইডি" টাইপ করুন), এবং আপনি সেখানে কোনও কাঁচা ডেটা পয়েন্টার ব্যবহার করতে পারবেন না (টাইপ "শূন্য *")। আপনি সংগ্রহের অভ্যন্তরে এটি ব্যবহার করার জন্য "আইডি" ধরণের [NSValue valueWithPointer:rawData]রূপান্তর করতে ব্যবহার করতে পারেন void *rawDdata। সাধারণভাবে "আইডি" আরও নমনীয় এবং এর সাথে সংযুক্ত বস্তুর সাথে সম্পর্কিত আরও শব্দার্থবিজ্ঞান রয়েছে। আইডি ধরণের উদ্দেশ্য সি এর ব্যাখ্যা এখানে আরও উদাহরণ রয়েছে ।

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