অবজেক্ট-সি-তে কীভাবে কোনও বস্তু নিক্ষেপ করা যায়


123

ভিবি.এনইটি-তে যেমন বস্তুগুলি কাস্ট করা হয় তেমনই কি বস্তুগত-সিতে বস্তুগুলি কাস্ট করার কোনও উপায় আছে?

উদাহরণস্বরূপ, আমি নিম্নলিখিতটি করার চেষ্টা করছি:

// create the view controller for the selected item
FieldEditViewController *myEditController;
switch (selectedItemTypeID) {
    case 3:
        myEditController = [[SelectionListViewController alloc] init];
        myEditController.list = listOfItems;
        break;
    case 4:
        // set myEditController to a diff view controller
        break;
}

// load the view
[self.navigationController pushViewController:myEditController animated:YES];
[myEditController release]; 

তবে আমি একটি সংকলক ত্রুটি পাচ্ছি যেহেতু 'তালিকা' সম্পত্তিটি সিলেকশনলিস্টভিউ কনট্রোলার ক্লাসে বিদ্যমান রয়েছে তবে ফিল্ডএডিটভিউ কনট্রোলারের ক্ষেত্রে ফিল্ডএডিটভিউ কনট্রোলারের উত্তরাধিকার সূত্রে প্রাপ্ত নয়।

এটি বোধগম্য হয়, তবে আমার 'অ্যাডিটকন্ট্রোলার' কে সিলেকশনলিস্টভিউ কনট্রোলারে কাস্ট করার কোনও উপায় আছে যাতে আমি 'তালিকা' সম্পত্তিটি অ্যাক্সেস করতে পারি?

উদাহরণস্বরূপ VB.NET এ আমি করব:

CType(myEditController, SelectionListViewController).list = listOfItems

সাহায্যের জন্য ধন্যবাদ!

উত্তর:


216

মনে রাখবেন, অবজেক্টিভ-সি হ'ল সি-সুপারিট, তাই টাইপকাস্টিং সি-তে যেমন কাজ করে:

myEditController = [[SelectionListViewController alloc] init];
((SelectionListViewController *)myEditController).list = listOfItems;

21
অথবা "মনে রাখবেন, অবজেক্টিভ-সি জাভা এর মতো কাজ করে, কেবল ওজেজে-সি অবজেক্টগুলিকে নির্দেশ করে এমন ভেরিয়েবলগুলিতে অ্যাসিরিস্টগুলি যুক্ত করতে ভুলবেন না।"
ড্যান রোজনস্টার্ক

1
দুর্দান্ত উত্তর। কাস্ট এবং অ্যাসাইনমেন্টটি দুটি লাইনে বিভক্ত করে আপনি এটিকে আরও পরিষ্কার করতে পারেন।
গুইডো আনসেলমি

1
উদ্দেশ্য-সিতে টাইপকাস্টিং জাভা থেকে অনেক বেশি পুরানো সি এর মতো। জাভা এর বেশিরভাগ ব্যবহারকারীর কাছ থেকে লুকিয়ে রাখে, তাই যুক্তি দেয় যে সি এখনও জাভা না করে প্রথম ভাষা হিসাবে শেখানো উচিত।
সিএসমিথ

11
((SelectionListViewController *)myEditController).list

আরও উদাহরণ:

int i = (int)19.5f; // (precision is lost)
id someObject = [NSMutableArray new]; // you don't need to cast id explicitly

7
সাধারণভাবে এটি সঠিক; বার্তা প্রকাশে আপনাকে আইডি কাস্ট করতে হবে না cast তবে বৈশিষ্ট্য অ্যাক্সেস করতে এবং সেট করতে ডট সিনট্যাক্স ব্যবহার করার সময় আপনাকে অবশ্যই একটি কংক্রিটের ধরণ ব্যবহার করতে হবে, কেবল আইডি নয়, তাই সংকলকটি জানে যে কী পদ্ধতিটি আহবান করতে হবে তা আসলে তৈরি করা। (এটি একই নামের বৈশিষ্ট্যগুলির জন্য পৃথক হতে পারে))
ক্রিস হ্যানসন

9

উদ্দেশ্য-সিতে টাইপকাস্টিং যেমন সহজ:

NSArray *threeViews = @[[UIView new], [UIView new], [UIView new]];
UIView *firstView = (UIView *)threeViews[0];

তবে, যদি প্রথম বস্তুটি না হয় UIViewএবং আপনি এটি ব্যবহার করার চেষ্টা করেন তবে কী হয় :

NSArray *threeViews = @[[NSNumber new], [UIView new], [UIView new]];
UIView *firstView = (UIView *)threeViews[0];
CGRect firstViewFrame = firstView.frame; // CRASH!

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

UIView *firstView = (UIView *)threeViews[0];
NSAssert([firstView isKindOfClass:[UIView class]], @"firstView is not UIView");

এই উক্তিগুলি খুব সুন্দর দেখাচ্ছে না, তাই আমরা এই কার্যকর বিভাগের সাথে তাদের উন্নতি করতে পারি:

@interface NSObject (TypecastWithAssertion)
+ (instancetype)typecastWithAssertion:(id)object;
@end


@implementation NSObject (TypecastWithAssertion)

+ (instancetype)typecastWithAssertion:(id)object {
    if (object != nil)
        NSAssert([object isKindOfClass:[self class]], @"Object %@ is not kind of class %@", object, NSStringFromClass([self class]));
    return object;
}

@end

এটি অনেক ভাল:

UIView *firstView = [UIView typecastWithAssertion:[threeViews[0]];

PS সংগ্রহের জন্য সুরক্ষা ধরণের সুরক্ষা এক্সকোড 7 টি টাইপকাস্টিং - জেনারিকের চেয়ে অনেক ভাল


4

অবশ্যই, বাক্য গঠনটি হ'ল সি'র মতোই - NewObj* pNew = (NewObj*)oldObj;

এই পরিস্থিতিতে আপনি এই তালিকাটি নির্মাণকারীর কাছে প্যারামিটার হিসাবে সরবরাহ করার বিষয়টি বিবেচনা করতে পারেন, এরকম কিছু:

// SelectionListViewController
-(id) initWith:(SomeListClass*)anItemList
{
  self = [super init];

  if ( self ) {
    [self setList: anItemList];
  }

  return self;
}

তারপরে এটি ব্যবহার করুন:

myEditController = [[SelectionListViewController alloc] initWith: listOfItems];

0

অন্তর্ভুক্তির জন্য কাস্টিং যেমন সি ++ প্রোগ্রামারকে বাদ দেওয়ার জন্য কাস্টিং তত গুরুত্বপূর্ণ। প্রকারের ingালাই আরটিটিআই-র সাথে একই নয় যে আপনি কোনও বস্তুকে কোনও ধরণের কাস্ট করতে পারেন এবং ফলস্বরূপ পয়েন্টারটি শূন্য হবে না।

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