2010-10-07 12 views
7

मुझे एक समस्या है कि एनएसटीकेनफ़िल्ल्ड में कई से अधिक रिश्ते मॉडल का प्रतिनिधित्व कैसे किया जाए। मैं दो (प्रासंगिक) मॉडल:एनएसटीकेनफ़ील्ड कोर डेटा का प्रतिनिधित्व करने वाले कई रिश्ते

आइटम टैग

एक आइटम कितने टैग हो सकता है और एक टैग कई मदों हो सकता है। तो यह एक उलझन में कई रिश्तों है।

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

ठीक है, आशा है कि आप अभी भी मेरे साथ हैं। मैं यह सब बाइंडिंग और सरणी नियंत्रकों के साथ करने की कोशिश कर रहा हूं (क्योंकि इससे अधिक समझ में आता है, है ना?)

मेरे पास एक एरे नियंत्रक है, "आइटम ऐरे कंट्रोलर", जो मेरे ऐप प्रतिनिधियों के लिए बाध्य है ऑब्जेक्ट कॉन्टेक्स्ट। सभी वस्तुओं को दिखाते हुए एक टेबलव्यू इस सरणी नियंत्रक के लिए बाध्यकारी है।

मेरा एनएसटीकेनफ़िल्ल्ड का मान सर नियंत्रक चयन कुंजी और मॉडल कुंजी पथ: टैग के लिए बाध्यकारी है।

इस कॉन्फ़िगरेशन के साथ, NSTokenField टैग नहीं दिखाएगा। यह सिर्फ मुझे देता है:

<NSTokenFieldCell: 0x10014dc60>: Unknown object type assigned (Relationship objects for {(
    <NSManagedObject: 0x10059bdc0> (entity: Tag; id: 0x10016d6e0 <x-coredata://9D77D47A-1171-4397-9777-706F599D7E3B/Tag/p102> ; data: <fault>) 
)} on 0x100169660). Ignoring... 

यह मुझे समझ में आता है, इसलिए कोई चिंता नहीं है। मैं NSTokenField प्रतिनिधि तरीकों में से कुछ पर देखा है और ऐसा लगता है कि मैं का उपयोग करना चाहिए:

- (NSString *)tokenField:(NSTokenField *)tokenField displayStringForRepresentedObject:(id)representedObject 

समस्या है, इस विधि कहा जाता है नहीं है और मैं पहले की तरह ही त्रुटि मिलती है।

ठीक है, इसलिए मेरा अगला कदम एक ValueTransformer को आजमाने और बनाने का था। टैग इकाई के साथ एक सरणी से रूपांतरण -> सरणी (टैग नाम) के साथ सरणी सभी अच्छी थी। दूसरा तरीका अधिक चुनौतीपूर्ण है।

मैंने जो भी प्रयास किया है वह है मेरे साझा ऐप प्रतिनिधि प्रबंधित ऑब्जेक्ट संदर्भ में हर नाम को देखना और मेल खाने वाले टैग को वापस करना। यह मुझे विभिन्न प्रबंधित ऑब्जेक्ट संदर्भों के साथ स्पष्ट रूप से एक समस्या देता है:

Illegal attempt to establish a relationship 'tags' between objects in different contexts (source = <NSManagedObject: 0x100156900> (entity: Item; id: 0x1003b22b0 <x-coredata://9D77D47A-1171-4397-9777-706F599D7E3B/Item/p106> ; data: { 
author = "0x1003b1b30 <x-coredata://9D77D47A-1171-4397-9777-706F599D7E3B/Author/p103>"; 
createdAt = nil; 
filePath = nil; 
tags =  (
); 
title = "Great presentation"; 
type = "0x1003b1150 <x-coredata://9D77D47A-1171-4397-9777-706F599D7E3B/Type/p104>"; 
}) , destination = <NSManagedObject: 0x114d08100> (entity: Tag; id: 0x100146b40 <x-coredata://9D77D47A-1171-4397-9777-706F599D7E3B/Tag/p102> ; data: <fault>)) 

मैं गलत कहां जा रहा हूं? मैं इसका कैसे समाधान करूं? क्या यह भी सही दृष्टिकोण है (मुझे लगता है कि आपको वैल्यू ट्रांसफॉर्मर का उपयोग करना होगा?)

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

+0

मैंने आज शोध करने में कुछ और समय बिताया - अभी भी संसाधनों को समझाने में सक्षम नहीं है। मुझे आशा है कि कोई यहां बचाव के लिए आएगा! :) – simonwh

उत्तर

7

मैं बाध्य NSManagedObject/TagNSSet और टोकन क्षेत्र की NSStringNSArray के बीच मैप करने के लिए एक कस्टम NSValueTransformer लिखा है।यहाँ 2 तरीके हैं:

- (id)transformedValue:(id)value { 
    if ([value isKindOfClass:[NSSet class]]) { 
    NSSet *set = (NSSet *)value; 
    NSMutableArray *ary = [NSMutableArray arrayWithCapacity:[set count]]; 
    for (Tag *tag in [set allObjects]) { 
     [ary addObject:tag.name]; 
    } 
    return ary; 
    } 
    return nil; 
} 

- (id)reverseTransformedValue:(id)value { 
    if ([value isKindOfClass:[NSArray class]]) { 
    NSArray *ary = (NSArray *)value; 
    // Check each NSString in the array representing a Tag name if a corresponding 
    // tag managed object already exists 
    NSMutableSet *tagSet = [NSMutableSet setWithCapacity:[ary count]]; 
    for (NSString *tagName in ary) { 
     NSManagedObjectContext *context = [[NSApp delegate] managedObjectContext]; 
     NSFetchRequest *request = [[NSFetchRequest alloc] init]; 

     NSPredicate *searchFilter = [NSPredicate predicateWithFormat:@"name = %@", tagName]; 
     NSEntityDescription *entity = [NSEntityDescription entityForName:[Tag className] inManagedObjectContext:context]; 

     [request setEntity:entity]; 
     [request setPredicate:searchFilter]; 

     NSError *error = nil; 
     NSArray *results = [context executeFetchRequest:request error:&error]; 
     if ([results count] > 0) { 
     [tagSet addObjectsFromArray:results]; 
     } 
     else { 
     Tag *tag = [[Tag alloc] initWithEntity:entity insertIntoManagedObjectContext:context]; 
     tag.name = tagName; 

     [tagSet addObject:tag]; 
     [tag release]; 
     } 
    } 
    return tagSet; 
    } 
    return nil; 
} 

CoreData स्वचालित रूप से वापसी पर वस्तु संबंधों की स्थापना करने लगता है (लेकिन मैं पूरी तरह से अभी तक इस सत्यापित नहीं किया है)

आशा है कि यह मदद करता है।

0

2 सवाल:

1) आप एक NSManagedObjectContext अन्य अपने अनुप्रयोग प्रतिनिधि के संदर्भ से इस्तेमाल किया जा रहा है? 2) क्या ऑब्जेक्ट जो टोकनफ़िल्ल्ड लागू करता है: displayStringForRepresentedObject: NSTokenField के प्रतिनिधि के रूप में सेट किया गया है?

1

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

आपकी प्रारंभिक त्रुटि एक अपूर्ण कुंजीपैथ के कारण होती है। आपके विवरण से ऐसा लगता है कि आप ItemsArrayController.selectedItem.tags के साथ टोकन फ़ील्ड को पॉप्युलेट करने का प्रयास कर रहे हैं, लेकिन यह केवल Tag ऑब्जेक्ट लौटाएगा जो टोकन दायर नहीं किया जा सकता है। इसके बजाए, आपको इसे कुछ ऐसी चीज प्रदान करने की आवश्यकता है जो स्ट्रिंग में परिवर्तित हो। ItemsArrayController.selectedItem.tags.name