অবজেক্টিভ-সি-তে কি জোরালোভাবে টাইপ করা সংগ্রহ রয়েছে?


140

আমি ম্যাক / আইফোন প্রোগ্রামিং এবং উদ্দেশ্য-সি তে নতুন। সি # এবং জাভাতে আমাদের "জেনেরিক্স" রয়েছে, সংগ্রহের ক্লাস রয়েছে যার সদস্যরা কেবল ঘোষিত ধরণের হতে পারে। উদাহরণস্বরূপ, সি # তে

Dictionary<int, MyCustomObject>

কেবলমাত্র এমন কীগুলি থাকতে পারে যা মাইকাস্টমঅবজেক্ট টাইপযুক্ত পূর্ণসংখ্যা এবং মান values অবজেক্টিভ-সি তে কি একই ধরণের ব্যবস্থা আছে?


আমি নিজেই ওজজিসি সম্পর্কে শিখতে শুরু করি। ভারী উত্তোলন করতে আপনি সম্ভবত ObjC ++ ব্যবহার করতে পারেন?
টয়বিল্ডার

আপনি এই প্রশ্নের উত্তরে আগ্রহী হতে পারেন: এনএসআরাই, এনএস মিটেবলআরে ইত্যাদিতে টাইপিং প্রয়োগ করার কোনও উপায় আছে কি? । উদ্দেশ্য-সি / কোকোতে কেন এটি সাধারণ অনুশীলন নয় তর্ক দেওয়া হয় are
mouviciel

2
ওবিজেসি ++ আসলে কোনও ভাষা নয় ... ওবিসি'র সি ++ ইনলাইন হ্যান্ডল করার ক্ষমতাটি ঠিক যেমন হ'ল সি'কে হ্যান্ডেল করবে তার উল্লেখ করার আরও একটি উপায়, যদিও আপনাকে যা না করা উচিত নয়, যদিও (যেমন আপনার প্রয়োজন হলে তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করতে যা সি ++ তে লেখা ছিল)।
মার্ক ডব্লিউ


@ মার্ক ডব্লিউ - "এটি করা উচিত নয়" কেন? আমি ObjC ++ ব্যবহার করেছি এবং এটি দুর্দান্ত কাজ করে। আমি # মিম্পোর্ট <ম্যাপ> এবং @ প্রপার্টি এসটিডি :: ম্যাপ <এনটি, এনএসএসআরটিং *> মাইডিক্ট; আমি সম্পূর্ণ কোকো এপিআই ব্যবহার করতে পারি এবং দৃ strongly়ভাবে টাইপ করা সংগ্রহগুলি। আমি কোনও ডাউন-সাইড দেখছি না।
জন হেন্কেল

উত্তর:


211

এক্সকোড In-তে অ্যাপল 'লাইটওয়েট জেনারিকস' অবজেক্টিভ-সি-এর সাথে পরিচয় করিয়েছে। অবজেক্টিভ-সি-তে, কোনও ধরনের মিল নেই তবে তারা সংকলক সতর্কতা তৈরি করবে।

NSArray<NSString*>* arr = @[@"str"];

NSString* string = [arr objectAtIndex:0];
NSNumber* number = [arr objectAtIndex:0]; // Warning: Incompatible pointer types initializing 'NSNumber *' with an expression of type 'NSString *'

এবং সুইফ্ট কোডে তারা একটি সংকলক ত্রুটি তৈরি করবে:

var str: String = arr[0]
var num: Int = arr[0] //Error 'String' is not convertible to 'Int'

লাইটওয়েট জেনারিকস NSArray, NSD অভিধান এবং NSSet এর সাথে ব্যবহার করার উদ্দেশ্যে করা হয়েছে, তবে আপনি সেগুলি নিজের ক্লাসেও যুক্ত করতে পারেন:

@interface GenericsTest<__covariant T> : NSObject

-(void)genericMethod:(T)object;

@end

@implementation GenericsTest

-(void)genericMethod:(id)object {}

@end

কম্পাইলার সতর্কতাগুলির সাথে উদ্দেশ্য-সি এর মতো আচরণ করবে।

GenericsTest<NSString*>* test = [GenericsTest new];

[test genericMethod:@"string"];
[test genericMethod:@1]; // Warning: Incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'

তবে সুইফট জেনেরিক তথ্য সম্পূর্ণ উপেক্ষা করবে। (সুইফট 3+ এ আর সত্য নয়))

var test = GenericsTest<String>() //Error: Cannot specialize non-generic type 'GenericsTest'

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

উদ্দেশ্য-সি এপিআইয়ের সাথে ইন্টারঅ্যাক্ট করা


: যেহেতু আমি জেনেরিক্স এবং পদ্ধতি ফিরে ধরনের সম্পর্কে প্রশ্ন আছে আমি বিভিন্ন থ্রেড আমার প্রশ্ন জিজ্ঞাসা করলেন, সবকিছু পরিষ্কার রাখার stackoverflow.com/questions/30828076/...
lvp

2
@rizzes। হ্যাঁ, এটি সবেমাত্র চালু হয়েছিল।
কনার

এখানে একটি সতর্কতা হ'ল সুইফ্ট আপনার জেনেরিক ওবিজেসি ক্লাসে টাইপ টিকাটি সম্পূর্ণরূপে উপেক্ষা করে না । আপনি যদি সীমাবদ্ধতাগুলি নির্দিষ্ট করেন, উদাহরণস্বরূপ MyClass <Foo: id<Bar>>, আপনার সুইফট কোডটি মানগুলি আপনার সীমাবদ্ধতার ধরণ বলে ধরে নেবে যা আপনাকে কাজ করার জন্য কিছু দেয় । তবে, বিশেষায়িত উপশ্রেণীর MyClassতাদের বিশেষ ধরণের উপেক্ষা করা হবে (জেনেরিকের মতো কার্যকরভাবে দেখা যাবে MyClass)। Github.com/bgerstle/ লাইটওয়েট জেনারিক্সের উদাহরণ
ব্রায়ান জারস্টেল

সুতরাং এই 10.10, 10.9 এবং পূর্ববর্তী অপারেটিং সিস্টেমের জন্য সংকলন করে?
p0lAris

আপনি যতক্ষণ না তাদের সমর্থন করার জন্য আপনার স্থাপনার লক্ষ্য নির্ধারণ করেন ততক্ষণ এটি হওয়া উচিত
কনার

91

এই উত্তরটি পুরানো তবে historicalতিহাসিক মানের জন্য রয়ে গেছে। এক্সকোড of হিসাবে, জুন 8 '15 থেকে কনারের উত্তরটি আরও সঠিক।


না, আপনি নিজের কাস্টম সংগ্রহের ক্লাসে সি ++ টেম্পলেট ব্যবহার করতে না চাইলে অবজেক্টিভ-সি তে কোনও জেনেরিক নেই (যা আমি দৃ strongly়ভাবে নিরুৎসাহিত করি)।

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

জভা এবং সি # এর মতো ভাষায় জেনেরিক্স প্রয়োজন কারণ তারা শক্তিশালী, স্ট্যাটিকালি টাইপ করা ভাষা। অবজেক্টিভ-সি এর গতিশীল টাইপিং বৈশিষ্ট্যের চেয়ে সম্পূর্ণ আলাদা বলগেম।


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

8
@ হেনিং 7777 হ্যাঁ, তবে উদ্দেশ্য-সি এই ভাষাগুলির চেয়ে আরও গতিশীল ভাষা। আপনি যদি শক্তিশালী টাইপ-সুরক্ষা চান তবে এই ভাষাগুলি ব্যবহার করুন।
রাফি খ্যাচাডৌড়িয়ান

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

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

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

11

না, তবে এটি পরিষ্কার করার জন্য আপনি যে ধরণের অবজেক্টটি সংরক্ষণ করতে চান তার সাথে এটি মন্তব্য করতে পারেন, আজকাল জাভা ১.৪-তে আপনাকে কিছু লেখার দরকার পড়লে আমি এটি কয়েকবার করে দেখেছি) যেমন:

NSMutableArray* /*<TypeA>*/ arrayName = ....

অথবা

NSDictionary* /*<TypeA, TypeB>*/ dictionaryName = ...

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

6

অবজেক্টিভ-সি-তে কোনও জেনেরিক নেই।

ডক্স থেকে

অ্যারেগুলি অবজেক্টগুলির সংগ্রহের আদেশ দেওয়া হয়। কোকো বেশ কয়েকটি অ্যারে ক্লাস, এনএসআরে, এনএস মিউটেবলআরে (এনএসআরির একটি সাবক্লাস) এবং এনএসপয়েন্টারআরে প্রদান করে।


উত্তরে ডকের লিঙ্কটি মারা গেছে - "দুঃখিত, সেই পৃষ্ঠাটি পাওয়া যাবে না"
পাইং

6

অ্যাপল এক্সকোড in-এ ওবজেসিতে জেনেরিকগুলি যুক্ত করেছে:

@property NSArray<NSDate *>* dates;
- (NSArray<NSDate *> *)datesBeforeDate:(NSDate *)date;
- (void)addDatesParsedFromTimestamps:(NSArray<NSString *> *)timestamps;

এখানে দেখুন: https://developer.apple.com/library/prerelease/mac/docamentation/Swift/Conceptual/BuildingCocoaapps/WorkingWithCocoaDataTypees.html#//apple_ref/doc/uid/TP40014216-CH6-ID61


5

এটি এক্সকোড 7 এ প্রকাশিত হয়েছিল (অবশেষে!)

লক্ষ্য করুন যে অবজেক্টিভ সি কোডে এটি কেবল একটি কম্পাইল-টাইম চেক; ভুল টাইপটি কেবল সংগ্রহের মধ্যে রাখার জন্য বা কোনও টাইপ করা সম্পত্তি অর্পণের জন্য রান-টাইম ত্রুটি থাকবে না।

ঘোষণা:

@interface FooClass <T> : NSObject
@property (nonatomic) T prop;
@end

ব্যবহার করুন:

FooClass<NSString *> *foo = [[FooClass alloc] init];
NSArray<FooClass<NSString *> *> *fooAry = [NSArray array];

যারা সম্পর্কে সতর্কতা অবলম্বন করুন *


4

জেনারিক এনএসআরাইগুলি সাবক্লাসিংয়ের মাধ্যমে উপলব্ধ করা যেতে পারে NSArray, এবং আরও সীমাবদ্ধতার সাথে সমস্ত সরবরাহিত পদ্ধতি পুনরায় সংজ্ঞায়িত করে। উদাহরণ স্বরূপ,

- (id)objectAtIndex:(NSUInteger)index

নতুন সংজ্ঞা দিতে হবে

@interface NSStringArray : NSArray

যেমন

- (NSString *)objectAtIndex:(NSUInteger)index

কোনও এনএসআর্রে কেবল এনএসএসআর্টিংগুলি অন্তর্ভুক্ত রাখতে।

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

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

ম্যাক্রোযুক্ত শিরোলেখ ফাইলটি আমদানির পরে, আপনি দুটি বয়ান সহ একটি জেনেরিক এনএসআরারি তৈরি করতে পারেন: একটি ইন্টারফেসের জন্য এবং একটি বাস্তবায়নের জন্য। আপনি কেবলমাত্র আপনার সাবক্লাসের জন্য সংরক্ষণ করতে চান এমন ডেটা টাইপ এবং নাম সরবরাহ করতে হবে। ডাব্লুএমজেনেরিক্যালক্ল্যাশন NSArray, NSDictionaryএবং NSSetপাশাপাশি তাদের পারস্পরিক পরিবর্তনীয় অংশগুলির জন্য এই জাতীয় টেমপ্লেট সরবরাহ করে ।

একটি উদাহরণ: List<int>কাস্টম নামে পরিচিত একটি ক্লাস দ্বারা উপলব্ধি করা যেতে পারে NumberArray, যা নিম্নলিখিত বিবৃতি দিয়ে তৈরি করা হয়েছে:

WMGENERICARRAY_INTERFACE(NSNumber *, // type of the value class
                         // generated class names
                         NumberArray, MutableNumberArray)

একবার আপনি তৈরি করার পরে NumberArray, আপনি এটি আপনার প্রকল্পের যে কোনও জায়গায় ব্যবহার করতে পারেন। এর সিনট্যাক্সের অভাব রয়েছে তবে <int>এগুলি ক্লাস হিসাবে টেমপ্লেট হিসাবে লেবেল করতে আপনি নিজের নামকরণ প্রকল্পটি চয়ন করতে পারেন।


নোট করুন যে একইটি কোরিলিবে রয়েছে: github.com/core-code/CoreLib/blob/master/CoreLib/CoreLib.h#L105
ব্যবহারকারী 1259710


2

এখন স্বপ্নগুলি সত্য হয় - আজ থেকে অবজেক্টিভ-সিতে জেনারিকস রয়েছে (ধন্যবাদ, ডাব্লুডাব্লুডিসি)। এটি কোনও রসিকতা নয় - সুইফটের অফিসিয়াল পৃষ্ঠায় :

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

এবং চিত্র এটি প্রমাণ করে:উদ্দেশ্য-সি জেনারিকস


2

শুধু এখানে লাফাতে চান। জেনারিক্স সম্পর্কে আমি এখানে একটি ব্লগ পোস্ট লিখেছি ।

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

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

উপভোগ করুন।


-2

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

Example:
    -(id) sort (id) obj;  // too generic. catches all.
     // better
    -(id) sort: (EasilySortableCollection*) esc;
    -(id) sort: (HardToSortCollection*) hsc; 
    ...
    [Sorter  sort: MyEasyColl];
    [Sorter  sort: MyHardColl];
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.