2011-12-21 18 views
8

बंद करने के बाद खो रहे हैं यह मेरी समस्या का अवलोकन है:कुछ CoreData रिश्तों एप्लिकेशन

जोड़ा जा रहा है (और इस बात की पुष्टि वे जुड़ जाते हैं) 1400 रिश्तों CoreDat में एक साबुन सेवा से लोड के बारे में। ऐप बंद करने और इसे फिर से खोलने के बाद कुछ रिश्ते खो गए हैं; मैं केवल उनमें से 800 देखता हूं (हालांकि यह भिन्न होता है)। इसके अलावा, मुझे कोई त्रुटि नहीं मिल रही है।

और अब, अधिक जानकारी के:

मैंने किसी चीज़ User बुलाया सेवाओं के लिए उपयोगकर्ता बचाया है के बारे में जानकारी है कि है, यह कुछ इस तरह दिखता है:

@interface OosUser : NSManagedObject 

    + (OosUser *) userFromSlug: (NSString *) slug; 
    @property (nonatomic, retain) NSString *name; 
    @property (nonatomic, retain) NSString *slug; 
    @property (nonatomic, retain) NSMutableSet /* Service */ *services; 
    - (void) addServicesObject: (Service *)service; 
    - (void) removeServicesObject: (Service *) service; 

@end 

@implementation User 

    @dynamic name; 
    @dynamic slug; 
    @dynamic services; 

    static NSString *fetchPredicate = @"slug = %@"; 

    + (User *) userFromSlug:(NSString *)slug 
    { 
     User *result = [super objectWithPredicate: fetchPredicate, slug]; 
     if (!result) { 
      result = [super create]; 
      result.slug = slug; 
     } 
    return result; 
    } 

@end 

कोड जहां डाटा प्रयोग किया जाता है के भाग में, रिश्तों इस तरह सहेजे जाते हैं:

NSMutableSet *userServices = self.user.services; 

for (Service *service in servicesToAdd) { 
     [self.services addObject: service]; 
     bool contained = false; 
     for (Service *userService in userServices) { 
      if ((contained = [userService.slug isEqualToString:service.slug])) { 
       break; 
      } 
     } 
     if (!contained) { 
      // [userServices addObject:service]; 
      [self.user addServicesObject: service]; 
      NSError *error = nil; 
      if (![[service managedObjectContext] save:&error]) { 
       NSLog(@"Saving failed"); 
       NSLog(@"Error: %@", [error localizedDescription]); 
      }else { 
       NSLog(@"Registered service %d: %@", self.services.count, service.slug); 
      } 
     } 
    } 

मामले है कि मैं के साथ की जाँच कर ली है डीबगर और मैं देख सकता हूं कि 1400 से अधिक रिलेशनशिप जोड़े गए हैं, लेकिन जब ऐप रीसेट हो जाता है और वे पुन: स्थापित होते हैं, हालांकि self.user.services मुझे केवल 800 ऑब्जेक्ट मिलते हैं।

यह क्यों हो सकता है? किसी के पास यह पहले था?

अग्रिम धन्यवाद।


अद्यतन:

लोग सुझाव है कि मैं कोर डेटा सही ढंग से उपयोग नहीं कर रहा है, लेकिन समस्या यह है कि डेटा एप्लिकेशन को पुन: प्रारंभ करने के बाद खत्म हो जाता है है रहते हैं। इसका उपयोग करते समय इसमें कोई समस्या नहीं है। मैं कोर डेटा को सही के रूप में उपयोग कर रहा हूं क्योंकि इसे ऐप्पल से प्राप्त सीमित दस्तावेज और उदाहरण दिए जा सकते हैं।

+0

आप प्रत्येक पुनरावृत्ति पर संदर्भ को सहेजते हैं? क्यूं कर? और आप उपयोगकर्ता को सेवा ऑब्जेक्ट कहां जोड़ते हैं? –

+0

मैं इसे पुनरावृत्ति के अंत में कर रहा था, लेकिन यह देखने के लिए ऐसा था कि क्या यह समस्या थी। मैं इसे 'userServices' में जोड़ता हूं जो उपयोगकर्ता से पुनर्प्राप्त एनएसएमयूटेबलसेट है। मैंने इसी तरह के परिणामों के साथ 'addServicesObject' का उपयोग करने का भी प्रयास किया है। – pablisco

+0

Ì लगता है कि आपको यह गलत लगता है कि कोर डेटा कैसे काम करता है।आपको सबसे पहले डीबी ऑब्जेक्ट में डालना चाहिए और फिर इसे एडसर्विसेज ऑब्जेक्ट के साथ जोड़ें: उपयोगकर्ता के संबंध में या इसे सहायक सेट में जोड़ें और फिर उपयोगकर्ता से संबंधों को सेवाओं से जोड़ने के लिए सेट करें: (एनएसएसएटी *) मान; विधि –

उत्तर

11
NSMutableSet *userServices = self.user.services; 

... 

      [userServices addObject:service]; 

ऐसा नहीं कर सकता। self.user.services एक म्यूटेबल सेट वापस नहीं करता है। यही है कि addServicesObject विधि के लिए है। दूसरी पंक्ति में बदलें:

  [self.user addServicesObject:service]; 

एप्पल प्रलेखन से:

यह मान डॉट एक्सेसर द्वारा और mutableSetValueForKey: द्वारा लौटाए के बीच का अंतर समझना महत्वपूर्ण है। mutableSetValueForKey: एक परिवर्तनीय प्रॉक्सी ऑब्जेक्ट देता है। यदि आप इसकी सामग्री को म्यूट करते हैं, तो यह रिश्ते के लिए उपयुक्त कुंजी-मूल्य अवलोकन (केवीओ) परिवर्तन अधिसूचनाओं को छोड़ देगा। डॉट एक्सेसर बस एक सेट देता है। आप के रूप में इस कोड टुकड़ा में दिखाया सेट में हेरफेर हैं:

[aDepartment.employees addObject:newEmployee]; // do not do this! then KVO change notifications are not emitted and the inverse relationship is not updated correctly.

याद रखें कि डॉट बस एक्सेसर विधि का आह्वान है, तो एक ही कारण के लिए:

[[aDepartment employees] addObject:newEmployee]; // do not do this, either!

+0

पहले टिप्पणी की, लेकिन मुद्दा भी नहीं। यह काम करता है क्योंकि कुछ वस्तुओं को फिर से लॉन्च करने के बाद बहाल किया जाता है। 'self.user.services' एक एनएसएमयूटेबलसेट लौटाता है, वास्तव में addServicesObject सहायक विधि जोड़ना वैकल्पिक है। 'user.services' [user valueForKeyPath: @" user.services "] के बराबर है। अन्यथा उनमें से कुछ कैसे बचते हैं? – pablisco

+0

क्या आप इस तरह के म्यूटेबल सेट एक्सेसर का उपयोग नहीं करना चाहिए: 'NSMutableSet * userServices = [self mutableSetValueForKeyPath: @" user.services "];'? – paulbailey

+0

@paulbailey नाह, 'user.service' – pablisco

3

मैं एक ही समस्या है, लेकिन व्यस्त संबंध स्थापित करने के बाद, सब कुछ ठीक है। मुझे आशा है कि इससे इस मुद्दे की जांच करने में मदद मिलेगी।

+0

मैंने कोशिश की लेकिन मुझे अभी भी याद आ रही है :( – pablisco

+0

वाह, यह सच है मेरा मामला। क्या बिल्ली है, सीडी रिश्ते को क्यों नहीं बचाएगी क्योंकि कोई रिवर्स रिलेशनशिप स्थापित नहीं है? ऐसे वैध मामले हैं जहां आप रिवर्स रिश्ते से बचना चाहते हैं। और यह स्पष्ट रूप से पिछले 4 वर्षों में तय नहीं हुआ है। – udondan

0

अंत में मैंने इसे एक कस्टम NSPredicate का उपयोग करके हल किया है जो एक विशेष पैरामीटर का उपयोग करके सेवाओं को प्राप्त करता है जिसे मैंने किसी उपयोगकर्ता द्वारा जोड़े जाने पर सेवाओं पर सेट किया है।

यह काम करता है हालांकि यह आदर्श नहीं है।

1

ठीक है, चलिए यहाँ लक्षण देखें। आप किसी संदर्भ में ऑब्जेक्ट्स में परिवर्तन कर रहे हैं, लेकिन जब आप ऐप को पुनरारंभ करते हैं, तो कुछ नहीं, लेकिन इन सभी परिवर्तनों में से कोई भी नहीं है।

इसका मतलब यह हो सकता है कि इन परिवर्तनों को लगातार स्टोर में नहीं लिखा जा रहा है। चूंकि आप कुछ बदलाव देख रहे हैं, इसलिए आप save: विधि को कॉल कर रहे हैं, लेकिन कोर डेटा सहेजने की आवश्यकता के अनुसार सभी ऑब्जेक्ट्स को पहचान नहीं रहा है।

इससे हमें यह पता चलता है कि आप कहां वस्तुओं में परिवर्तन कर रहे हैं। क्या आप केवीओ-अनुरूप तरीके से बदलाव कर रहे हैं? कोर डेटा केवीओ पर निर्भर करता है कि क्या परिवर्तन हुए हैं, और इसलिए किन परिवर्तनों को जारी रखने की आवश्यकता है। यदि आप ऑब्जेक्ट्स को गैर-केवीओ फैशन में बदलते हैं, तो जब आप उनकी जांच करेंगे तो वे बदल जाएंगे, लेकिन कोर डेटा नहीं जानता कि ये परिवर्तन मौजूद हैं, और इसलिए यह नहीं पता होगा कि उन्हें जारी रखना चाहिए।

इस प्रकार मैं अपने कोड में संशोधन होता है, Service वस्तु उपलब्ध कराने उलटा User वापस करने के लिए संबंध नहीं है (और उस रिश्ते user कहा जाता है, और एक 1 एम का हिस्सा):

[servicesToAdd setValue:self.user forKey:@"user"]; 

NSError *error = nil; 
if (![[service managedObjectContext] save:&error]) { 
    NSLog(@"Saving failed"); 
    NSLog(@"Error: %@", [error localizedDescription]); 
} 

यह निर्भर करता है इस तथ्य पर कि कोर डेटा आपके लिए रिश्ते के दोनों सिरों का ख्याल रखेगा, जहां एक व्यस्त संबंध स्थापित किया गया है। बेशक, यदि यह कई से अधिक रिश्ते हैं, तो कोड थोड़ा अलग है, लेकिन हम अभी भी परिवर्तन करने के लिए केवीओ-अनुरूप तरीकों का उपयोग करते हैं।

[servicesToAdd setValue:self.user forKey:@"user"]; 

for (Service *service in servicesToAdd) { 
    [user addServicesObject:service]; 
} 

NSError *error = nil; 
if (![[service managedObjectContext] save:&error]) { 
    NSLog(@"Saving failed"); 
    NSLog(@"Error: %@", [error localizedDescription]); 
} 
+0

यह एक एमएम रिश्ते है। अब मैं पहचानता हूं कि मैं वस्तुओं को जोड़ने के लिए सीधे डॉट एक्सेसर का उपयोग नहीं कर सकता और मैं यह भी समझ रहा था कि सीडी रिवर्स रिश्तों का ख्याल रखती है। इसके अलावा, मैंने इसके बजाय 'addServicesObject' का उपयोग करने का प्रयास किया है इसी तरह के परिणामों के साथ डॉट एक्सेसर का। – pablisco

+0

आप यह जांच रहे हैं कि ऑब्जेक्ट पहले से सेट में है या नहीं। मुझे लगता है कि यह शायद एक अनावश्यक परिसर है ity। बस सेट में सेवा जोड़ें, और कोको और कोर डेटा निर्धारित करें कि यह एक है) पहले से ही (एक 'एनएसएमयूटेबलसेट' एक ही ऑब्जेक्ट को दो बार जोड़ने की अनुमति नहीं देता है) और बी) क्या कोई बदलाव है जिसके लिए बचत की आवश्यकता है लगातार स्टोर ढांचे को आपके लिए काम करने दें जहां वे कर सकते हैं। – paulbailey

+0

मैंने जोड़ा कि एक अलग फिक्स के रूप में क्योंकि मैं डुप्लिकेट प्राप्त कर रहा था।लेकिन यह एक अलग कहानी है (मुझे लगता है)। मुझे पता है कि आपके पास एक ही वस्तु नहीं हो सकती है लेकिन आपके पास एक ही डेटा के साथ दो ऑब्जेक्ट हो सकते हैं। और बचत कार्य केवल यह देखने का प्रयास था कि क्या समस्या थी। मैं उन्हें पहले सेव नहीं कर रहा था। – pablisco

0

मेरे पास एक ही समस्या थी जब भी मैं ऐप को पुनरारंभ करता हूं। मैंने घंटों की खोज की। अंत में मुझे मुद्दा मिला। मैंने अपने रिश्ते को Transient के रूप में घोषित किया, इससे इस समस्या का कारण बन गया।

enter image description here

0

मेरे लिए, इस मुद्दे को उलटा संबंध

था अपने मॉडल नहीं है

enter image description here

सभी है इस तरह व्युत्क्रम संबंध में सक्षम बनाना है:

enter image description here

enter image description here

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