2012-12-27 26 views
9

अधिकांश (सभी मैंने देखा है) कोर डाटा ट्यूटोरियल के साथ निम्नलिखित कोड का उपयोग करते @"MyEntityClass" हार्ड-कोडेड में:क्या NSStringFromClass ([MyEntityClass क्लास]) एक सुरक्षित कोर डेटा इकाई नाम उत्पन्न करता है?

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"MyEntityClass"]; 

यह के रूप में एक इकाई नाम NSStringFromClass() उपयोग करने के लिए सुरक्षित है?

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([MyEntityClass class])]; 

यह रिफैक्टरिंग और पसंद के बारे में से निपटने के लिए बहुत easer होने के लिए तेजी। खासकर जब से मैं एक्सकोड कर रहा हूं मेरे NSManagedObject सबक्लास बनाते हैं। मैं पूछता हूं क्योंकि मैंने इसे पहले कभी नहीं देखा है, इसलिए शायद मुझे कुछ याद आ रहा है।

उत्तर

14

हाँ, यह कोड ठीक है, यदि आपकी इकाई का वर्ग MyEntityClass पर आपके मॉडल में सेट है।

+ (NSString *)entityName { 
    return NSStringFromClass(self); 
} 

और इसे इस तरह कहते हैं:

मैं इकाई वर्ग एक वर्ग विधि उस संस्था का नाम देता है देने के लिए पसंद करते हैं

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:[MyEntityClass entityName]]; 

इस तरह, यदि मैं कक्षा बदलना चाहते हैं मॉडल में इकाई का नाम बदलने के बिना नाम, मैं बस कक्षा विधि में परिवर्तन कर सकता हूं:

+ (NSString *)entityName { 
    return @"NewEntityName"; 
} 

मैं ऐसा क्यों करूं? खैर, मैं इकाई के लिए एक बेहतर नाम पर फैसला कर सकता हूं। कक्षा का नाम बदलने से मौजूदा कोर डेटा लगातार स्टोर के साथ संगतता नहीं टूटती है, लेकिन मॉडल फ़ाइल में इकाई का नाम बदलता है। मैं कक्षा का नाम बदल सकता हूं, और entityName विधि, लेकिन मॉडल में इकाई नाम अपरिवर्तित छोड़ दें, और फिर मुझे माइग्रेशन के बारे में चिंता करने की आवश्यकता नहीं है। (लाइटवेट माइग्रेशन नामित इकाइयों का समर्थन करता है, इसलिए यह किसी भी तरह का सौदा नहीं है।)

आप आगे जा सकते हैं और वास्तव में entityName विधि रनटाइम पर प्रबंधित ऑब्जेक्ट मॉडल से इकाई का नाम देख सकते हैं। मान लीजिए कि आपके आवेदन प्रतिनिधि एक संदेश में कामयाब ऑब्जेक्ट मॉडल रिटर्न है:

+ (NSString *)entityName { 
    static NSString *name; 
    static dispatch_once_t once; 
    dispatch_once(&once, ^{ 
     NSString *myName = NSStringFromClass(self); 
     NSManagedObjectModel *model = [(AppDelegate *)[UIApplication delegate] managedObjectModel]; 
     for (NSEntityDescription *description in model.entities) { 
      if ([description.managedObjectClassName isEqualToString:myName]) { 
       name = description.name; 
       break; 
      } 
     } 
     [NSException raise:NSInvalidArgumentException 
      format:@"no entity found that uses %@ as its class", myName]; 
    }); 
    return name; 
} 

जाहिर है, अगर तुम सच में ऐसा करना चाहते हैं, तो आप बाहर dispatch_once ब्लॉक की सामग्री को एक सहायक विधि में अपने एप्लिकेशन पर कारक चाहिए, शायद प्रतिनिधि (या जहां भी आप मॉडल प्राप्त करते हैं)।

+0

यदि आप अतिरिक्त लुकअप कोड जोड़ने के लिए अभी तक नहीं जाना चाहते हैं, तो आप 'इकाई नाम' के किसी भी आंतरिक पहुंच से पहले इस जोर को जोड़ सकते हैं। 'NSAssert (context.persistentStoreCoordinator.managedObjectModel.entitiesByName [[self entityName]]! = Nil, @" मॉडल% नाम के साथ इकाई @ मॉडल में नहीं मिली है। क्या आपकी कक्षा का नाम आपकी इकाई नाम जैसा ही है? ", [Self entityName ]); 'यह आपको रनटाइम पर एक त्रुटि जारी करेगा यदि आपके मॉडल का इकाई नाम आपकी कक्षा के नाम से मेल नहीं खाता है। इस मामले में –

+0

आपको प्रत्येक ऑटो जेनरेट ऑब्जेक्ट की श्रेणी में कोड जोड़ना होगा? केवल इस समारोह को जोड़ने के लिए कक्षाओं के लिए नई फ़ाइल बनाने के बारे में चिंतित है। –

+0

@VitaliK आप 'NSManagedObject' में एक श्रेणी जोड़ सकते हैं, लेकिन यदि आप ऐसा करते हैं, तो इसे' entityName' नाम न दें क्योंकि यह बहुत सामान्य है। नाम टकराव से बचने के लिए 'Vitali_entityName' जैसे उपसर्ग का उपयोग करें। –