উত্তর:
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
প্রতিক্রিয়া জানায় সে সম্পর্কে কোনও অনুমান করা যায় না । একটি id
সহজেই কোনও শ্রেণীর উদাহরণকে উল্লেখ করতে পারে যা অন্তর্নিহিত নয় NSObject
। ব্যবহারিকভাবে বলতে গেলে, আপনার বক্তব্যটি সত্যিকারের বিশ্বের আচরণের সাথে সেরা মেলে; আপনি <NSObject>
ফাউন্ডেশন এপিআইয়ের সাথে অ- প্রয়োগকারী ক্লাসগুলি মিশ্রিত করতে পারবেন না এবং খুব দূরে যেতে পারবেন, এটি অবশ্যই নিশ্চিত!
id
এবং Class
প্রকারগুলিকে এআরসি এর অধীনে ধরে রাখতে সক্ষম অবজেক্ট পয়েন্টার হিসাবে বিবেচনা করা হচ্ছে । সুতরাং অনুমানটি কমপক্ষে এআরসি-র অধীনে সত্য।
আইডি হ'ল উদ্দেশ্য সি অবজেক্টের পয়েন্টার, যেখানে শূন্য * হ'ল কোনও কিছুর পয়েন্টার।
আইডি অজানা মথগুলিকে কল করার সাথে সম্পর্কিত সতর্কতাগুলিও বন্ধ করে দেয়, উদাহরণস্বরূপ:
[(id)obj doSomethingWeirdYouveNeverHeardOf];
অজানা পদ্ধতি সম্পর্কে সাধারণ সতর্কতা দেবে না। এটি অবশ্যই রান সময়ে ব্যাতিক্রম বাড়িয়ে তুলবে যদি না আপত্তি শূন্য হয় বা সত্যই এই পদ্ধতিটি বাস্তবায়ন করে না।
প্রায়শই আপনার ব্যবহার করা উচিত NSObject*
বা তার id<NSObject>
পছন্দ হিসাবে id
, যা অন্তত নিশ্চিত করে যে প্রত্যাবর্তিত বস্তুটি কোকো অবজেক্ট, তাই আপনি নিরাপদে এটি রক্ষণ / প্রকাশ / অটোরিলেজের মতো পদ্ধতি ব্যবহার করতে পারেন।
Often you should use NSObject*
পরিবর্তে আমি একমত নই id
। নির্দিষ্ট করে NSObject*
আপনি প্রকৃতপক্ষে স্পষ্ট করে বলছেন যে বস্তুটি একটি এনএসবজেক্ট। অবজেক্টে যেকোনো মেথড কলের ফলে একটি সতর্কতা দেখা দেবে, তবে যতক্ষণ না সেই বস্তুটি প্রকৃতপক্ষে পদ্ধতি কলটির প্রতিক্রিয়া জানায় ততক্ষণ কোনও রানটাইম ব্যতিক্রম হবে না। সতর্কতা স্পষ্টত বিরক্তিকর তাই id
ভাল। মোটা id<MKAnnotation>
দাগের পরে আপনি উদাহরণস্বরূপ আরও নির্দিষ্ট করে বলতে পারেন , যা এই ক্ষেত্রে যার অর্থ যা কিছুই হোক না কেন এটি অবশ্যই এমকেএনোটেশন প্রোটোকলের সাথে খাপ খায়।
যদি কোনও পদ্ধতিতে রিটার্নের ধরণ থাকে তবে id
আপনি যে কোনও অবজেক্টি-সি অবজেক্টটি ফিরিয়ে দিতে পারেন।
void
মানে, পদ্ধতিটি কোনও কিছুই ফেরত দেবে না।
void *
শুধু পয়েন্টার। আপনি যে পয়েন্টারটিতে ইঙ্গিত করেছেন ঠিকানার লিখিত সামগ্রীটি সম্পাদনা করতে পারবেন না।
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 ।
void *
টাইপড ভেরিয়েবলগুলি অবশ্যই পদ্ধতি আহ্বানের লক্ষ্য হতে পারে - এটি একটি সতর্কতা, ত্রুটি নয়। শুধু আপনি এই কাজ করতে যে পারেন: int i = (int)@"Hello, string!";
এবং আপ অনুসরণ করুন: printf("Sending to an int: '%s'\n", [i UTF8String]);
। এটি একটি সতর্কতা, ত্রুটি নয় (এবং ঠিক প্রস্তাবিত নয়, বা বহনযোগ্যও নয়)। তবে আপনি কেন এই জিনিসগুলি করতে পারবেন তা সমস্ত মৌলিক সি
/// 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 থেকে এসেছে, সুতরাং দেখে মনে হচ্ছে আইডি হ'ল অ্যাজজেক্ট_বজেক্ট স্ট্রাক্টের উদাহরণ এবং আইএসএ পয়েন্টারটি যে কোনও অবজেক্টিভ সি ক্লাস অবজেক্টের সাথে আবদ্ধ হতে পারে, যখন অকার্যকর * কেবল একটি টাইপড পয়েন্টার।
আমার বোধগম্যতা হল যে আইডি কোনও বস্তুর পয়েন্টার উপস্থাপন করে যখন শূন্য * সত্যিই যে কোনও কিছুতে নির্দেশ করতে পারে, যতক্ষণ আপনি এটি টাইপ করতে না চান ততক্ষণ আপনি এটি ব্যবহার করতে চান
ইতিমধ্যে যা বলা হয়েছে তা ছাড়াও সংগ্রহের সাথে সম্পর্কিত অবজেক্ট এবং পয়েন্টারের মধ্যে পার্থক্য রয়েছে। উদাহরণস্বরূপ, আপনি যদি এনএসআরাইতে কিছু রাখতে চান তবে আপনার একটি অবজেক্টের প্রয়োজন ("আইডি" টাইপ করুন), এবং আপনি সেখানে কোনও কাঁচা ডেটা পয়েন্টার ব্যবহার করতে পারবেন না (টাইপ "শূন্য *")। আপনি সংগ্রহের অভ্যন্তরে এটি ব্যবহার করার জন্য "আইডি" ধরণের [NSValue valueWithPointer:rawData]
রূপান্তর করতে ব্যবহার করতে পারেন void *rawDdata
। সাধারণভাবে "আইডি" আরও নমনীয় এবং এর সাথে সংযুক্ত বস্তুর সাথে সম্পর্কিত আরও শব্দার্থবিজ্ঞান রয়েছে। আইডি ধরণের উদ্দেশ্য সি এর ব্যাখ্যা এখানে আরও উদাহরণ রয়েছে ।
id
সাড়া দেওয়ার জন্য অনুমান করা হয়েছে-retain
এবং-release
অন্যদিকেvoid*
কলির কাছে সম্পূর্ণ অস্বচ্ছ। আপনি কোনও স্বেচ্ছাসেবক পয়েন্টারটি পাস করতে পারবেন না-performSelector:withObject:afterDelay:
(এটি অবজেক্টটি ধরে রাখে) এবং আপনি ধরে নিতে পারবেন না যে+[UIView beginAnimations:context:]
প্রসঙ্গটি ধরে রাখা হবে (অ্যানিমেশন প্রতিনিধি প্রসঙ্গে তার মালিকানা বজায় রাখতে হবে; ইউআইকিট অ্যানিমেশন প্রতিনিধি ধরে রাখে)।