45

मेरे पास एक लेनदेन डालने के लिए एक उपयोगकर्ता इंटरफ़ेस है। एक बार जब उपयोगकर्ता प्लस पर क्लिक करता है तो उसे स्क्रीन मिलती है और मैं अपने कोर डेटा एनएसएमएनेज ऑब्जेक्ट इकाई को तुरंत चालू करना चाहता हूं ताकि उपयोगकर्ता उस पर काम कर सके। फिर जब उपयोगकर्ता सहेजें बटन पर क्लिक करता है तो मैं सेव फ़ंक्शन को कॉल करूंगा।क्या इसे सम्मिलित किए बिना एनएसएमएनेज्ड ऑब्जेक्ट को तुरंत चालू करने का कोई तरीका है?

तो कोड के लिए नीचे:

transaction = (Transaction *)[NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:self.managedObjectContext]; 
//even if i dont call save: its going to show up on my table 
[self.managedObjectContext save:&error] 

पी.एस मैं कि मेज पर एक NSFetchedResultsController का उपयोग कर रहा है और मुझे लगता है कि NSFetchedResultsController एक वर्ग और मेज पर एक वस्तु डालने कर रहा है।

मेरा विचार यह है कि यदि लेनदेन NSManagedObject को तुरंत चालू करने का कोई तरीका है, तो मैं ग्राहक को तब तक सहेजने के साथ अपडेट कर सकता हूं जब तक क्लाइंट बंद नहीं हो जाता।

उत्तर

16

एक शून्य एमओसी का उपयोग करने में एक मौलिक समस्या है: विभिन्न एमओसी में ऑब्जेक्ट्स एक दूसरे को संदर्भित नहीं करना चाहिए — यह संभवतः तब भी लागू होता है जब किसी रिश्ते के एक पक्ष में शून्य एमओसी होता है। यदि आप बचाते हैं तो क्या होता है? (क्या होता है जब आपके ऐप का दूसरा भाग बचाता है?)

यदि आपके ऑब्जेक्ट में रिश्ते नहीं हैं, तो ऐसी कई चीजें हैं जो आप कर सकते हैं (जैसे एनएससीओडी)।

आप एनएसपी्रेडिकेट में -[NSManagedObject isInserted] का उपयोग करने में सक्षम हो सकते हैं (संभवतः यह सम्मिलित करने और सफलतापूर्वक सहेजने के बीच हाँ है)।वैकल्पिक रूप से, आप एक ही व्यवहार के साथ एक क्षणिक संपत्ति का उपयोग कर सकते हैं (इसे जागृत करने में YES पर सेट करें और WillSave में नहीं)। यदि आपके ऐप का एक अलग हिस्सा बचाता है तो ये दोनों समस्याग्रस्त हो सकते हैं।

एक दूसरे एमओसी का उपयोग करना यह है कि कैसे CoreData का उपयोग किया जाना चाहिए "हालांकि; यह आपके लिए स्वचालित रूप से संघर्ष पहचान और संकल्प को संभालता है। बेशक, आप हर बार एक नया एमओसी बनाना नहीं चाहते हैं; धीमे "उपयोगकर्ता थ्रेड" द्वारा सहेजे गए परिवर्तनों के लिए एक एमओसी होना बेहद समझदार हो सकता है यदि आपको यूआई के कुछ हिस्सों को अन्य हिस्सों में सहेजे गए परिवर्तनों को नहीं देखते हैं (अंतर-एमओसी संचार का ओवरहेड नगण्य है)।

+0

हाय @ टीसी। मैंने पहली प्रतिक्रिया की कोशिश की जो InManagedObjectContext को सम्मिलित करना है: शून्य लेकिन फिर जब मैं एक रिश्ते को असाइन करना चाहता था तो ऐप त्रुटि से दुर्घटनाग्रस्त हो गया: कारण: विभिन्न संदर्भों में वस्तुओं के बीच 'रिश्ते को स्थापित करने का अवैध प्रयास' श्रेणी। तो मुझे लगता है कि मेरा सवाल यह है कि एक संदर्भ एनएसएएनएजेड ऑब्जेक्ट और संदर्भ प्रबंधित ऑब्जेक्ट के बीच संबंध बनाने के लिए कानूनी नहीं है, तो समाधान क्या होगा? –

+0

मैंने बिना किसी संदर्भ के एक श्रेणी इकाई को उसी तरह बनाया, लेकिन जब यह सहेजने के लिए आया तो मैंने संदर्भ में दोनों को जोड़ा और फिर यह अच्छी तरह से काम किया। –

+2

मैं इस उत्तर की शुद्धता को प्रमाणित कर सकता हूं।मैं किसी ऑब्जेक्ट के संदर्भ संदर्भ से संबंधित किसी मुद्दे से थोड़ा सा हो गया। किसी संदर्भ को जोड़ने से पहले ऑब्जेक्ट को असाइन किए गए विशेषता मान मूल संदर्भ में प्रचार नहीं करते हैं जब अंततः ऑब्जेक्ट को बाल संदर्भ जोड़ा जाता है। दृढ़ता स्टोर में गुण 'शून्य' के रूप में संग्रहीत किए जाते हैं। जब मैंने ऑर्डर को स्विच किया (यानी इसे संदर्भ में डालने के बाद विशेषता मान असाइन करें), चीजें ठीक से काम करती हैं। कहानी का नैतिक है, संदर्भ के बिना किसी ऑब्जेक्ट को तुरंत चालू करना अच्छा विचार नहीं है। –

8

प्रबंधित ऑब्जेक्ट संदर्भ के लिए nil पास करके -[NSManagedObject initWithEntity:insertIntoManagedObjectContext:] के साथ आप NSManagedObjectContext डाल सकते हैं। आपको निश्चित रूप से इसे एक संदर्भ में असाइन करना होगा (सहेजने से पहले -[NSManageObjectContext insertObject:] का उपयोग करना। यह, जहां तक ​​मुझे पता है, वास्तव में कोर डेटा में इच्छित पैटर्न नहीं है, लेकिन (@ mzarra का उत्तर here देखें)। कुछ मुश्किल आदेश हैं मुद्दों (यानी यह सुनिश्चित करना कि इंस्टेंस को एक संदर्भ में आवंटित होने से पहले एक संदर्भ में असाइन किया गया हो)। अधिक मानक पैटर्न एक नया प्रबंधित ऑब्जेक्ट संदर्भ बनाना है और उस संदर्भ में अपनी नई वस्तु डालना है। जब उपयोगकर्ता बचाता है, सहेजता है संदर्भ, और NSManagedObjectDidSaveNotification को अपने 'मुख्य' संदर्भ में परिवर्तनों को मर्ज करने के लिए संभाल लें। यदि उपयोगकर्ता लेनदेन को रद्द कर देता है, तो आप केवल संदर्भ को उड़ाते हैं और अपने व्यवसाय के साथ आगे बढ़ते हैं।

+0

db से मुझे लगता है कि तुम्हारा मतलब 'NSManagedObject', नहीं' NSManagedObjectContext' बचत होगी। किसी भी तरह से, ऐसा नहीं लगता कि आप एमओसी को बदल सकते हैं एक एनएसएमएनेज ऑब्जेक्ट — से जुड़ा हुआ है, आप इसे '- [एनएसएमएनेज ऑब्जेक्ट कॉन्टेक्स्ट असाइन ऑब्जेक्ट: toPersistentStore:] 'के साथ भ्रमित कर सकते हैं। –

+0

@ टीसी, टाइपो पकड़ के लिए धन्यवाद। –

30

इसके लायक होने के लिए, मार्कस ज़रारा लगता है nil संदर्भ दृष्टिकोण को बढ़ावा देने के लिए, दावा करते हुए कि एक नया संदर्भ बनाना महंगा है। अधिक detai के लिए एलएस, एक समान प्रश्न के लिए this answer देखें।

अद्यतन

मैं वर्तमान में शून्य संदर्भ दृष्टिकोण का उपयोग कर रहा हूँ और कुछ है कि दूसरों के हित के लिए हो सकता है सामना करना पड़ा। किसी संदर्भ के बिना प्रबंधित ऑब्जेक्ट बनाने के लिए, आप initWithEntity:insertIntoManagedObjectContext:NSManagedObject विधि का उपयोग करें। इस विधि के लिए ऐप्पल के दस्तावेज़ीकरण के अनुसार:

If context is not nil , this method invokes [context insertObject:self] (which causes awakeFromInsert to be invoked).

यहां निहितार्थ महत्वपूर्ण है। एक प्रबंधित ऑब्जेक्ट बनाते समय nil संदर्भ का उपयोग करके insertObject: को कॉल करने से रोका जाएगा और इसलिए awakeFromInsert को कॉल होने से रोकें। नतीजतन, में किए गए किसी भी ऑब्जेक्ट प्रारंभिक या डिफ़ॉल्ट संपत्ति मानों की सेटिंग nil संदर्भ का उपयोग करते समय स्वचालित रूप से नहीं हो जाएगी।

नीचे पंक्ति: किसी संदर्भ के बिना प्रबंधित ऑब्जेक्ट का उपयोग करते समय, awakeFromInsert स्वचालित रूप से नहीं कहा जाएगा और आपको क्षतिपूर्ति के लिए अतिरिक्त कोड की आवश्यकता हो सकती है।

+0

नमस्ते यह थोड़ी देर के लिए काम करता है जब तक कि मैंने अपने लेनदेन और एक श्रेणी NSManagedObject के बीच संबंध स्थापित करने की कोशिश की। तो ऐप उस वजह से दुर्घटनाग्रस्त हो गया। क्या इसके चारों ओर कोई रास्ता है? –

+0

यदि आपको संबंध स्थापित करने की आवश्यकता है, तो मैं दो संदर्भ दृष्टिकोण के साथ जाऊंगा। टीसी के रूप में बताते हैं, विभिन्न संदर्भों में वस्तुओं को एक दूसरे का संदर्भ नहीं दिया जाना चाहिए। दूसरी तरफ, आप उन रिश्तों को तब तक सेट अप स्थगित कर सकते हैं जब तक * आप अपने मुख्य संदर्भ में नई असंबद्ध वस्तु को सम्मिलित न करें। –

17
यहाँ

कैसे मैं इसे बाहर काम किया है:

प्रस्तुत होने पर, जहाँ हम जानते हैं कि हम एक नया लेनदेन के साथ काम कर रहे हैं, मैं संदर्भ किसी अन्य दुकान से बाहर बनाया। बचाने के लिए

if(transaction.managedObjectContext == nil){ 
     NSEntityDescription *entity = [NSEntityDescription entityForName:@"Category" inManagedObjectContext:self.managedObjectContext]; 
     Category *category = (Category *)[[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil]; 
     category.title = ((Category *)obj).title; 
     transaction.category = category; 
     [category release]; 
    } 
    else { 
     transaction.category = (Category *)obj; 
    } 

और अंत में:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Transaction" inManagedObjectContext:self.managedObjectContext]; 
     transaction = (Transaction *)[[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil]; 

तो जब यह एक संबंध जहाज मैं ऐसा किया स्थापित करने के लिए आया था

if (transaction.managedObjectContext == nil) { 
     [self.managedObjectContext insertObject:transaction.category]; 
     [self.managedObjectContext insertObject:transaction]; 
    } 
    //NSLog(@"\n saving transaction\n%@", self.transaction); 

    NSError *error; 
    if (![self.managedObjectContext save:&error]) { 
     // Update to handle the error appropriately. 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     exit(-1); // Fail 
    } 
+0

मैं सोच रहा था कि क्या मैं कर सकता था ... लेनदेन = (लेनदेन *) [एनएसईएनटीटी डिस्क्रिप्शन डालने न्यूजब्जेक्टफोरइन्टिटीफोरनाम: @ "लेनदेन" में प्रबंधित किया गया ऑब्जेक्ट कॉन्टेक्स्ट: संदर्भ]; और फिर लेनदेन .managedObjectContext = शून्य; क्या यह गलत होगा? – yunas

2

एक NSManagedObject शून्य के रूप में उपयोग करते हुए बनाया जा सकता है संदर्भ, लेकिन अगर वहां अन्य एनएसएमएजेडऑब्जेक्ट्स को लिंक करना होगा तो इसके परिणामस्वरूप एक त्रुटि होगी। जिस तरह से मैं इसे करता हूं, मैं गंतव्य स्क्रीन में संदर्भ पास करता हूं और उस स्क्रीन में एक NSManagedObject बनाता हूं। सभी परिवर्तनों को अन्य NSManagedObjects लिंक करें। यदि उपयोगकर्ता रद्द बटन को टैप करता है तो मैं NSManagedObject को हटाता हूं और संदर्भ को सहेजता हूं। यदि उपयोगकर्ता सहेजें बटन को टैप करता है तो मैं NSManagedObject में डेटा अपडेट करता हूं, इसे संदर्भ में सहेजता हूं, और स्क्रीन को छोड़ देता हूं। स्रोत स्क्रीन में मैं एक रीलोड के साथ तालिका अद्यतन करता हूं।

गंतव्य स्क्रीन में NSManagedObject को हटाने से फ़ाइल को अद्यतन करने के लिए कोर डेटा समय मिलता है। टेबलव्यू में बदलाव न देखने के लिए आमतौर पर यह पर्याप्त समय होता है। आईफोन कैलेंडर ऐप में आपको उस समय से देरी होती है जब यह तालिकादृश्य में दिखाई देने पर सहेजी जाती है। इसे यूआई स्टैंड पॉइंट से अच्छी बात माना जा सकता है कि आपका उपयोगकर्ता उस पंक्ति पर ध्यान केंद्रित करेगा जो अभी जोड़ा गया था। आशा है कि ये आपकी मदद करेगा।

-3
transaction = (Transaction *)[NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:nil]; 

अगर पिछले परम नहीं के बराबर है, यह एक NSManagedObject लौटने के बिना

+0

यह विफलता का कारण बन जाएगा: *** अपरिपक्व अपवाद के कारण ऐप को समाप्त करना 'एनएसआईएनवालिडअर्गमेंट एक्सेप्शन', कारण: '+ entityForName: nil कानूनी नाम नहीं है NSManagedObjectContext पैरामीटर इकाई नाम के लिए खोज रहा है ... – c9s

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

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