ऑब्जेक्टिव-सी में ऑब्जेक्ट कैसे डालें


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]; 

हालाँकि, मुझे 'लिस्ट' के बाद से एक संकलक त्रुटि मिल रही है, क्योंकि SelectionListViewController क्लास में प्रॉपर्टी मौजूद है, लेकिन FieldEditViewController पर भी नहीं है जबकि SelectionListViewController FieldEditViewController से विरासत में मिली है।

यह समझ में आता है, लेकिन वहाँ एक रास्ता है एक चयन सूची के लिए myEditController कास्ट करने के लिए तो मैं 'सूची' संपत्ति का उपयोग कर सकते हैं?

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
सामान्य तौर पर यह सही है; आपको संदेश अभिव्यक्तियों में आईडी डालने की आवश्यकता नहीं है। लेकिन संपत्तियों तक पहुंचने और सेट करने के लिए डॉट सिंटैक्स का उपयोग करते समय, आपको केवल आईडी नहीं, बल्कि एक ठोस प्रकार का उपयोग करना होगा, इसलिए कंपाइलर जानता है कि वास्तव में उत्पन्न करने के लिए किस विधि का आह्वान किया गया है। (यह समान नाम वाले गुणों के लिए भिन्न हो सकता है।)
क्रिस हैनसन

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 संग्रह प्रकार सुरक्षा के लिए Xcode 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

समावेश के लिए कास्टिंग सी ++ प्रोग्रामर के लिए अपवर्जन के लिए कास्टिंग के रूप में महत्वपूर्ण है। टाइप कास्टिंग, आरटीटीआई के साथ इस अर्थ में नहीं है कि आप किसी भी प्रकार की वस्तु डाल सकते हैं और परिणामी सूचक शून्य नहीं होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.