2009-02-01 16 views
17

में कोरडाटा-इकाइयों को सहेजें कोरडाटा इकाई की कल्पना करें (उदा। searchEngine नामित)।
NSManagedObjectContext इस इकाई के कुछ "उदाहरण" प्रबंधित करता है।
अंतिम उपयोगकर्ता NSPopupButton के साथ अपने "standard searchEngine" का चयन करने में सक्षम होने जा रहा है।
एनएसपीओपअप बटन के selected object एनएसयूसर डीफॉल्ट पर बाध्य होना चाहिए।
समस्या:NSUserDefaults

1) @try {बचाने}

a) आप NSUserDefaults करने के लिए चयनित "उदाहरण" सीधे बचाने की कोशिश अगर वहाँ कुछ इस तरह आता है:

-[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value ' (entity: searchEngine; id: 0x156f60 ; data: { 
    url = " http://google.de/ "; 
    someAttribute = 1; 
    name = "google"; 
})' of class 'searchEngine'.

b) हैं आप "इंस्टेंस" को एनएसडीटा में कनवर्ट करने का प्रयास करते हैं:

-[searchEngine encodeWithCoder:]: unrecognized selector sent to instance 0x1a25b0

तो किसी भी विचार को इस संस्था को एक प्लेस्ट-संगत डेटा में कैसे प्राप्त किया जाए?

2) @try {registerDefaults}

आमतौर पर registerDefaults: विधि + (void)initialize में कार्यान्वित किया जाता। यहां समस्या यह है कि कोरडाटा सहेजे गए इकाइयों को अपने डेटाबेस से लोड करने से पहले इस विधि को बुलाया जाता है। तो मैं एक मौजूदा वस्तु के लिए डिफ़ॉल्ट सेट नहीं कर सकता, है ना?

मुझे पता है, लंबे समय से सवाल ... लेकिन: try {[मुझे प्रदान करते हैं: विवरण]}; D

उत्तर

6

आप कोशिश करते हैं और एक कोर डेटा इकाई को संग्रहीत और यह स्टोर करने के लिए नहीं करना चाहते। इसके बजाए, आप कुंजी या कुछ अन्य ज्ञात विशेषता संग्रहित करेंगे और एप्लिकेशन शुरू होने पर इकाई को लाने के लिए इसका उपयोग करेंगे।

कुछ उदाहरण कोड (थोड़ा उदाहरण Core Data Programming Guide में तैनात से संशोधित):

NSManagedObjectContext *moc = [self managedObjectContext]; 
NSEntityDescription *entityDescription = [NSEntityDescription 
    entityForName:@"SearchEngine" inManagedObjectContext:moc]; 
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
[request setEntity:entityDescription]; 

NSPredicate *predicate = [NSPredicate predicateWithFormat: 
    @"engineName LIKE[c] '%@'", selectedEngineName]; 
[request setPredicate:predicate]; 

NSError *error = nil; 
NSArray *array = [moc executeFetchRequest:request error:&error]; 
if (array == nil) 
{ 
    // Deal with error... 
} 

इस तरह आप उपयोगकर्ता चूक में नाम बचाने के लिए और जब आवश्यक इकाई लाने।

NSURL *moIDURL = [[myManagedObject objectID] URIRepresentation]; 

फिर आप उपयोगकर्ता चूक के लिए URL बचा सकते हैं:

+0

Mmh। क्या आपको पता है कि क्यों 'सरणी! = शून्य' लेकिन '[सरणी गिनती] <0' ... यह काम नहीं करना चाहता ... – papr

+0

यदि सरणी है! = शून्य तो कोई त्रुटि नहीं है लेकिन कोई रिकॉर्ड भी नहीं हो सकता है लौटा ([सरणी गिनती] == 0) ... हालांकि, [सरणी गिनती] <0 * कभी * नहीं हो सकता क्योंकि गिनती संदेश एक NSUInteger प्रकार देता है। संकलक सबसे अधिक संभावना है कि इस तरह के किसी भी परीक्षण ([सरणी गिनती] <0) स्ट्रिप्स। –

+0

हाँ। मेरा मतलब था ([सरणी गिनती] == 0)। उसके लिए खेद है। मैं केवल यह व्यक्त करना चाहता था कि इस सरणी में कुछ भी नहीं है। ;) – papr

33

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

प्रबंधित वस्तु पुनः प्राप्त करने के लिए, आप का उपयोग करें:

NSManagedObjectID *moID = [myPersistentStoreCoordinator managedObjectIDForURIRepresentation:moIDURL]; 
NSManagedObject *myManagedObject = [myContext objectWithID:moID]; 

केवल चेतावनी है कि आप यह सुनिश्चित करना चाहिए कि मूल प्रबंधित वस्तु आईडी स्थायी है - यह एक समस्या है, तो आप पहले से ही सहेज कर रखा है नहीं है ऑब्जेक्ट, वैकल्पिक रूप से आप obtainPermanentIDsForObjects:error: का उपयोग कर सकते हैं।

+3

मुझे लगता है कि यह एक साफ समाधान है। एक छोटा सा जोड़ा, क्योंकि NSUserDefaults के लिए प्रलेखन कहता है, आपको NSURL ऑब्जेक्ट्स को NSData के रूप में संग्रहित करने की आवश्यकता है। इसलिए NSRL को बचाने के लिए बेकार नहीं है। मैंने अभी यह गलती की है और जब मैं ऑब्जेक्ट को पुनर्प्राप्त करने का प्रयास करता हूं तो शून्य हो रहा है। ध्यान दें कि NSUserDefaults में एक setURL है: forKey: विधि। मुझे नहीं लगता कि यह इस समय आईफोन ओएस के लिए उपलब्ध है। – tilish

+7

setURL: forKey: आईओएस 4.0 में उपलब्ध है और बाद में – djskinner

+1

BE BEWARE! टिलिश की टिप्पणी महत्वपूर्ण है, सही समाधान यहां है: http://stackoverflow.com/a/516735/1780492 इसके बिना आपको त्रुटि संदेश मिलेगा: "गैर-संपत्ति सूची ऑब्जेक्ट को सम्मिलित करने का प्रयास x-coredata:" – BootMaker

6

वर्तमान में setURL और getURL विधियों को 4 में जोड़े जाने का यह सबसे आसान और सबसे छोटा तरीका है।0 NSKeyedUnarchiver और NSKeyedArchiver करने के लिए अतिरिक्त कॉल से बचने के लिए:

सेटर:

+ (void)storeSomeObjectId:(NSManagedObjectID *)objectId 
{ 
    [[NSUserDefaults standardUserDefaults] setURL:[objectId URIRepresentation] 
              forKey:@"someObjectIdKey"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 
} 

मनुष्य:

+ (SomeManagedObject *)getObjectByStoredId 
{ 
    NSURL *uri = [[NSUserDefaults standardUserDefaults] URLForKey:@"someObjectIdKey"]; 
    NSManagedObjectID *objectId = [self.persistentStoreCoordinator managedObjectIDForURIRepresentation:uri]; 
    SomeManagedObject *object = [self.managedObjectContext objectWithID:objectId]; 
} 
संबंधित मुद्दे