2013-01-23 19 views
7

क्या कोई यह समझा सकता है कि किंडऑफ क्लास उदाहरण के निर्माण के आधार पर अलग-अलग परिणाम क्यों देता है?isKindOfClass व्यवहार

@interface BaseClass 
... 

@interface DerivedClassA : BaseClass 
... 

DerivedClassA *instance = [[DerivedClassA alloc] init]; 

[instance isKindOfClass:[BaseClass class]]; // yields YES 

Class c = NSClassFromString(@"DerivedClassA"); 
id instance = [[c alloc] init]; 

[instance isKindOfClass:[BaseClass class]]; // yields NO 

डीबगर में दो प्रकार से मैं जो कुछ भी प्राप्त कर सकता हूं वह समान है। मैं NSStringFromClass ([उदाहरण superclass]) के दोनों परिणामों की तुलना भी कर सकता हूं और वे बराबर हैं।

मुझे कुछ आसान याद आना चाहिए।

अपडेट किया गया कोड

इस इकाई परीक्षण कोड है।

LightingUnit *u1 = [[LightingUnit alloc] init]; 

STAssertTrue([u1 isKindOfClass:[ModelBase class]], @"should be derived from base"); 

Class uc = NSClassFromString(@"LightingUnit"); 
id u2 = [[uc alloc] init]; 

STAssertTrue([u2 isKindOfClass:[ModelBase class]], @"should be derived from base"); 

यहां कक्षा परिभाषाएं हैं।

@interface ModelBase : NSObject 

@property (readonly) NSString *__type; 

- (id)initWithDictionary:(NSDictionary *)dictionary; 

- (NSMutableDictionary *)dictionary; 

@end 

@interface LightingUnit : ModelBase 

@property (strong, nonatomic) NSString *name; 
@property NSInteger unitId; 

@end 

संभावित जवाब

जब मैं इस मुद्दे के बिना परीक्षण वातावरण के अपने काम करता है बाहर इस तर्क को चलाते हैं। जाहिर है, केवल अंतर ही STAssertTrue कथन को हटा रहा है और उन्हें मेरी स्थितियों से बदल रहा है। इस मामले में वे दोनों हाँ वापस आते हैं। मैंने एक सरलीकृत उदाहरण (आधार या व्युत्पन्न में कोई भी इवर्स) बनाने की कोशिश की और यह परीक्षण में विफल रहता है लेकिन मानक रनटाइम में काम करता है।

कोई विचार क्यों परीक्षण करते समय यह केवल एक मुद्दा हो सकता है? क्या मेरा परीक्षण लक्ष्य कुछ खो रहा है?

हल

मैं परीक्षण लक्ष्य सूत्रों संकलन में मीटर फ़ाइलें शामिल था। एक बार हटा दिए जाने के बाद यह अपेक्षित व्यवहार करना शुरू कर दिया। इसे हल करने में मेरी सहायता के लिए this post पर धन्यवाद।

+0

बस कोशिश की, दो हाँ प्राप्त करें। 'instance' –

+0

की श्रेणी मुद्रित करने का प्रयास करें क्या यह 'बेस क्लास: NSObject' होना चाहिए? उस प्रश्न का उत्तर आपके प्रश्न का उत्तर बदल देगा। – Ephemera

+1

आपको अपना असली कोड पेस्ट करने की आवश्यकता है। आपका नमूना कोड ठीक काम करता है, जब तक मैं 'बेस क्लास' को 'NSObject' का उप-वर्ग बना देता हूं (यह अन्यथा संकलित भी नहीं करता है)। –

उत्तर

2

मैंने अपना कोड एक परीक्षण ऐप में जोड़ा। मुझे दो instance चरों का नाम बदलना पड़ा, इसके बाद संकलक ने मुझे एक चेतावनी दी ("क्लास विधि '+ एलोक' नहीं मिला"), और जब मैंने इसे चलाया तो प्रोग्राम क्रैश हो गया।

@interface BaseClass : NSObject 

अर्थात मैं NSObject से BaseClass व्युत्पन्न:

मैं तो इस लाइन बदल दिया है। कोई और संकलक चेतावनी नहीं है और कोड अपेक्षित के रूप में चलता है, यानी दूसरा isKindOfClass हाँ देता है।

मुझे नहीं पता कि गायब NSObject आपकी समस्या का कारण बनता है या नहीं। यदि ऐसा नहीं है तो किसी और को कदम उठाना होगा। अगर ऐसा है, तो मुझे आश्चर्य है कि आप अपना कोड कैसे चला सकते हैं।

2

NSObject से विरासत इस कोड के परिणाम को बदल देगा या नहीं। यहाँ दो संभावनाएं हैं:


@interface BaseClass 

आप BaseClassनिर्धारित किया है तोNSObject से इनहेरिट बिना, तो काफी स्पष्ट रूप से मैं हैरान संकलक आप अपने instance चर की स्थापना के साथ भाग जाओ हूँ। जब तक आप और -initBaseClass (जो संभव हो) पर विधियों को परिभाषित नहीं करते हैं, तो आपके परीक्षण की पहली पंक्ति बिल्कुल काम नहीं करेगी। यदि आपने उचित +alloc और -init विधि को परिभाषित किया है, तो भी आप -isKindOfClass: के साथ परेशानी में भाग लेंगे क्योंकि आपको स्वयं को परिभाषित करने की आवश्यकता होगी। तो मूल रूप से यह काम नहीं करेगा, अगले विकल्प को देखो ...


@interface BaseClass : NSObject 

अपने परीक्षण की पहली पंक्ति (instance बनाने) ठीक काम करना चाहिए।

[instance isKindOfClass:[BaseClass class]] उचित मूल्य, YES देता है।

आपकी class c प्रारंभिकरण सही ढंग से काम करना चाहिए।

मुझे लगता है कि वहाँ कुछ यहाँ छोड़े गए क्योंकि अंतिम पंक्ति कोड आप पोस्ट (NSObject से BaseClass inherits कल्पना करते हुए) के साथ YES लौटना चाहिए ... अंतिम पंक्ति YES लौट जाना है। मुझे संदेह है कि क्या हो सकता है instance किसी भी तरह गलत गड़बड़ी/टाइपो/आदि के माध्यम से nil युक्त घायल हो गया है। इस मामले में, इसे एक संदेश भेजकर nil वापस आ जाएगा, और इस प्रकार -isKindOfClass भेजकर NO मिलेगा।

संबंधित मुद्दे