objective c - CoreData के लिए एक गलती को पूरा नहीं कर सका




objective-c ios (4)

ऐसा इसलिए होता है क्योंकि आप पहली कॉल के अपने सभी रिश्तों को पूरा करने से पहले अपनी नई पंक्ति में "यादृच्छिक संदेश" जोड़ रहे हैं।

आलसी लोडिंग से बचने के लिए आप अपने पहले कॉल में प्रीफेच जोड़ सकते हैं और समस्या हल हो जाएगी, मुझे विश्वास है।

इस प्रकार हम अनुरोध के लिए प्रीफेचिंग कर सकते हैं:

[request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects:@"whatEverOfYourWillNumberOne",@"whatEverOfYourWillNumberTwo", nil]];

उम्मीद है की वो मदद करदे।

मुझे वास्तव में परेशान करने वाली समस्या है, जिसे मैं ठीक नहीं लग रहा हूं।

मेरे पास एक दृश्य है जब मैं एक संदेश भेजता हूं जो कोर डेटा में सहेजा जाता है, जब ऐसा किया जाता है तो उसने डेटाबेस को यादृच्छिक संदेश (वाक्य) के लिए कहा और डेटाबेस में एक अन्य पंक्ति के साथ सहेजा।

यदि मैं डीबी से डेटा लाने के बिना हार्डकोड किया गया अंतिम भाग करता हूं, तो यह सभी ठीक और बेवकूफ काम करता है, लेकिन जैसे ही मैं डीबी से यादृच्छिक पंक्ति प्राप्त करता हूं, यह पागल हो जाता है।

मेरे AppDelegate.m में:

- (void)save {
    NSAssert(self.context != nil, @"Not initialized");
    NSError *error = nil;
    BOOL failed = [self.context hasChanges] && ![self.context save:&error];
    NSAssert1(!failed,@"Save failed %@",[error userInfo]);
}

- (NSString*)selectRandomSentence
{
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Sentences" inManagedObjectContext:self.managedObjectContext];
    [request setEntity:entity];

    NSError *error = nil;
    NSUInteger count = [self.context countForFetchRequest:request error:&error];

    NSUInteger offset = count - (arc4random() % count);
    [request setFetchOffset:offset];
    [request setFetchLimit:1];

    NSArray *sentenceArray = [self.context executeFetchRequest:request error:&error];

    [request release];

    return [[sentenceArray objectAtIndex:0] sentence];
}

- (NSManagedObjectContext *)context {

    if (_managedObjectContext != nil)
        return _managedObjectContext;

    NSPersistentStoreCoordinator *coordinator = [self coordinator];
    if (coordinator != nil) {
        _managedObjectContext = [[NSManagedObjectContext alloc] init];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }

    return _managedObjectContext;
}

मेरे ChatController.m में:

- (void)didRecieveMessage:(NSString *)message
{
    [self addMessage:message fromMe:NO];
}

#pragma mark -
#pragma mark SendControllerDelegate

- (void)didSendMessage:(NSString*)text {
    [self addMessage:text fromMe:YES];
}

#pragma mark -
#pragma mark Private methods

- (void)responseReceived:(NSString*)response {
    [self addMessage:response fromMe:NO];
}

- (void)addMessage:(NSString*)text fromMe:(BOOL)fromMe {
    NSAssert(self.repository != nil, @"Not initialized");
    Message *msg = [self.repository messageForBuddy:self.buddy];
    msg.text = text;
    msg.fromMe = fromMe;

    if (fromMe)
    {
        [self.bot talkWithBot:text];
    }

    [self.repository asyncSave];

    [self.tableView reloadData];
    [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:[self.buddy.messages count] - 1] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

मेरे ऑफ़लाइनबॉट.एम में:

- (void)talkWithBot:(NSString *)textFromMe
{
    AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    [self didRecieveMessage:[delegate selectRandomSentence]];
}

- (void)didRecieveMessage:(NSString *)message
{
    if ([self.delegate respondsToSelector:@selector(didRecieveMessage:)])
        [self.delegate didRecieveMessage:message];
}

Repository.m

- (Message*)messageForBuddy:(Buddy*)buddy {
    Message *msg = [self.delegate entityForName:@"Message"];
    msg.source = buddy;
    [self.delegate.managedObjectContext refreshObject:buddy mergeChanges:YES];
    return msg;
}

- (void)asyncSave {
    [self.delegate save];
}

त्रुटि:

2012-08-10 00: 28: 20.526 चैट [13170: c07] * में दावा विफलता - [AppDelegate save], /Users/paulp/Desktop/TestTask/Classes/AppDelegate.m:28 2012-08-10 00:28 : 20.527 चैट [13170: c07] * अपरिपक्व अपवाद के कारण ऐप को समाप्त करना 'एनएसआईएननल इन्फॉन्सिस्टेंसी अपवाद', कारण: 'असफल सहेजें {टाइप = अपरिवर्तनीय dict, count = 2, प्रविष्टियां => 1: {सामग्री = "NSAffectedObjectsErrorKey"} = ("( इकाई: वाक्य; आईडी: 0x6b8bf10; डेटा:) ") 2: {सामग्री =" NSUnderlyingException "} = कोरडाटा '0x6b8bf10'} के लिए कोई गलती नहीं कर सका

मैं क्या गलत कर रहा हूं?

अद्यतन मैं इस पंक्ति में त्रुटि pinpointed:

NSArray *sentenceArray = [self.context executeFetchRequest:request error:&error];

जब मैं उस पंक्ति को निष्पादित करता हूं, तो मुझे त्रुटि मिलती है ... वह डेटा लाने पर होता है। त्रुटि संदेश, संदेश इकाई में नया डेटा सहेजते समय चालू हो रहा है। यादृच्छिक वाक्य वाक्य से प्राप्त किया जाता है।

मैंने सीधे सहेजने के लिए asyncSave विधि को बदलने के बाद (इस प्रकार एक नया धागा उपयोग नहीं किया) यह पहली बातचीत बचाता है, लेकिन उसके बाद कुछ भी नहीं। वह मरता है।

अपडेट करें यह सब मेरे द्वारा किया गया काम करने के लिए काम करता है didFinishLaunchingWithOptions :

[self.context setRetainsRegisteredObjects:YES];

मैं समझता हूं कि इस प्रकार कोडडाटा ऑब्जेक्ट मॉडल संदर्भ अपनी ऑब्जेक्ट्स को रिलीज़ नहीं करता है, जो कि betweens जोड़ने और सहेजने में समस्या है। पर क्यों?


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


यह अलग-अलग पंक्तियों में कोर डेटा ऑब्जेक्ट्स को " सहेजने " के लिए वास्तव में अवधारणात्मक रूप से संभव नहीं है। याद रखें, कोर डेटा एक ऑब्जेक्ट ग्राफ़ है और डेटाबेस नहीं है।

यदि आप अपनी सजा को "स्थानांतरित करना" चाहते हैं, तो इसका सबसे अच्छा तरीका इसे नष्ट करना और इसे फिर से बनाना है। यदि आप पुराना उदाहरण रखना चाहते हैं, तो बस एक नया बनाएं और फिर मौजूदा से गुणों को भरें।

नष्ट करने के लिए, उपयोग करें

[self.context deleteObject:sentenceObject];

पुनर्निर्माण के लिए, उपयोग करें

Sentence *newSentence = [NSEntityDescription insertNewObjectForEntityForName:
  "Sentences" inManagedObjectContext:self.context];
newSentence.sentence = sentenceObject.sentence;
// fill in other properties, then
[self.context save:error];

यदि आप इस पर पढ़ना चाहते हैं, तो "कोर डेटा प्रोग्रामिंग गाइड" के "प्रबंधित ऑब्जेक्ट्स का उपयोग करना" अनुभाग में " कॉपी और कॉपी और पेस्ट " देखें।


हम्म। क्या आप इस गाइड के बाद समेकन को सही ढंग से कार्यान्वित कर रहे हैं ? कई थ्रेडों में कोर डेटा का उपयोग करते समय आप जो समस्या देख रहे हैं वह एक आम है। ऑब्जेक्ट को आपके "पृष्ठभूमि संदर्भ" में हटा दिया गया था, जबकि तब इसे किसी अन्य संदर्भ से एक्सेस किया जा रहा है। [context processPendingChanges] जाने के बाद आपके पृष्ठभूमि संदर्भ पर [context processPendingChanges] को कॉल करना, लेकिन सहेजने से पहले मदद कर सकता है।

कोर डेटा प्रदर्शन को अनुकूलित करने पर एक डब्ल्यूडब्ल्यूडीसी 2010 सत्र (137) भी है जो थोड़ा सा हट जाता है।

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

ध्यान दें कि उपर्युक्त Concurrency गाइड अब पुराना है, आपको पुराने थ्रेड कैदीकरण मॉडल की बजाय माता-पिता के संदर्भ और निजी कतार समेकन का उपयोग करना चाहिए। कई कारणों से अभिभावक-बाल संदर्भ "गलती को पूरा नहीं कर सका ..." में भागने की संभावना कम है। और कृपया, एक दस्तावेज बग दर्ज करें या प्रतिक्रिया फॉर्म का उपयोग करें ताकि अनुरोध किया जा सके कि concurrency गाइड को अपडेट किया जाए।







nsmanagedobjectcontext