NSOrderedSet जनरेट किए गए एक्‍सेसर्स में अपवाद


364

मेरे शेर ऐप पर, मेरे पास यह डेटा मॉडल है:

यहां छवि विवरण दर्ज करें

subitemsअंदर संबंध Item का आदेश दिया जाता है

Xcode 4.1 (4B110 निर्माण) मेरे लिए फ़ाइल पैदा कर दी है Item.h, Item.m, SubItem.hऔरSubItem.h

यहाँ सामग्री (स्वतःपूर्ण) है Item.h:

#import <Foundation/Foundation.h>

#import <CoreData/CoreData.h>

@class SubItem;

@interface Item : NSManagedObject {
@private
}

@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSOrderedSet *subitems;
@end

@interface Item (CoreDataGeneratedAccessors)

- (void)insertObject:(SubItem *)value inSubitemsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromSubitemsAtIndex:(NSUInteger)idx;
- (void)insertSubitems:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeSubitemsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInSubitemsAtIndex:(NSUInteger)idx withObject:(SubItem *)value;
- (void)replaceSubitemsAtIndexes:(NSIndexSet *)indexes withSubitems:(NSArray *)values;
- (void)addSubitemsObject:(SubItem *)value;
- (void)removeSubitemsObject:(SubItem *)value;
- (void)addSubitems:(NSOrderedSet *)values;
- (void)removeSubitems:(NSOrderedSet *)values;

@end

और यहाँ की सामग्री (स्वतःपूर्ण) है Item.m:

#import "Item.h"
#import "SubItem.h"

@implementation Item

@dynamic name;
@dynamic subitems;

@end

जैसा कि आप देख सकते हैं, क्लास Itemनामक एक विधि प्रदान करता है addSubitemsObject:। दुर्भाग्य से, जब इसे इस तरह से उपयोग करने की कोशिश की जा रही है:

Item *item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
item.name = @"FirstItem";

SubItem *subItem = [NSEntityDescription insertNewObjectForEntityForName:@"SubItem" inManagedObjectContext:self.managedObjectContext];

[item addSubitemsObject:subItem];

यह त्रुटि दिखाई देती है:

2011-09-12 10:28:45.236 Test[2002:707] *** -[NSSet intersectsSet:]: set argument is not an NSSet

क्या आप मेरी मदद कर सकते हैं?

अपडेट करें:

मेरी बग रिपोर्ट से सिर्फ १, August August दिनों के बाद, आज (१ अगस्त, २०१६) Apple ने मुझे यह लिखा: "कृपया इस मुद्दे को नवीनतम iOS १० बीटा बिल्ड से सत्यापित करें और अपने परिणामों के साथ bugreport.apple.com पर अपनी बग रिपोर्ट अपडेट करें।" । चलिए आशा करते हैं कि यह सही समय है :)


5
मैं एक ही मुद्दा देख रहा हूं। उम्मीद है कि यह जल्द ही ठीक हो जाए। हालांकि सीधे सेट किए गए म्यूटेबल का उपयोग करना समय के लिए एक आसान समाधान है। नोट: मैं mogenerator का उपयोग कर रहा हूं, लेकिन मुझे लगता है कि यह जेनरेट किए गए कोड के इस हिस्से के लिए आंतरिक रूप से समान Apple जनरेटर का उपयोग कर रहा है।
चाड पोडोस्की

12
यह लगभग 2 साल है! क्या आप इसे iOS 7, Apple में ठीक करेंगे? —– मैं सिर्फ उन लोगों के साथ यह सोचकर साझा करना चाहता हूं कि क्या यह बग अभी भी है: "हां, यह है।"
AN0

1
दो साल के बहुत करीब, यह अभी भी सभी xcode 5 डेवलपर पूर्वावलोकन में एक मुद्दा है।
कोर्विन श्यांतो

2
क्या आप अभी भी समस्या को देखते हैं यदि आप उपयुक्त केवीसी एक्सेसर का उपयोग करते हैं? (यानी mutableOrderedSetValueForKey:)
8

3
अभी भी Mavericks पर एक मुद्दा हो सकता है।
टिम

जवाबों:


263

मैंने आपका सेटअप आपके डेटा मॉडल और मेरे स्वयं के दोनों अलग-अलग नामों से पुन: पेश किया। मुझे दोनों मामलों में एक ही त्रुटि मिली।

ऐपल के ऑटोजेनरेटेड कोड में एक बग जैसा दिखता है।


60
बग आईडी 10114310 है। यह 13-सितंबर -2018 को बताया गया था लेकिन आज (15-जनवरी -2018) यह अभी भी "खुला" है। यह अविश्वसनीय है, एक ही समस्या वाले लोगों की संख्या को देखते हुए।
देव

14
अपडेट: आज (11 मई, 2012) बग # 10114310 अभी भी खुला है, मेरी रिपोर्ट (24 सितंबर, 2011) के 241 दिन बाद। अविश्वसनीय।
देव

23
मैं सिर्फ एक WWD पर CoreData लैब सत्र के दौरान एक Apple इंजीनियर के साथ इसे लाया। वे इस मुद्दे को स्वीकार करते हैं और यह एक वास्तविक बग है, और मैंने जो देखा है, उसमें "महत्वपूर्ण" स्थिति है, लेकिन निश्चित रूप से कोई वादा नहीं है जब वे इसे ठीक करेंगे। मुझे नहीं लगता कि यह iOS6 / माउंटेन लायन में तय किया जाएगा। मुझे लगता है कि आगे इस रडार को डुप्लिकेट करना अच्छा होगा। वर्तमान में यह लगभग 25 है, और अधिक बेहतर है!
DaGaMs

40
बस आज की जाँच की, यह अभी भी iOS 7 GM / OMG में है! मुझे विश्वास नहीं हो रहा है ...
a0

79
अद्यतन: 797 दिन, 2 नए प्रमुख iOS संस्करण, और अनगिनत Xcode संस्करण बीत चुके हैं क्योंकि मैंने बग # 10114310 भरा है। और यह अभी भी "खुला है।" अविश्वसनीय।
देव

244

मैं मानता हूं कि यहां बग हो सकता है। मैंने NSMutableOrderedSet में सही तरीके से जोड़ने के लिए ऐड ऑब्जेक्ट सेटर के कार्यान्वयन को संशोधित किया है।

- (void)addSubitemsObject:(SubItem *)value {
    NSMutableOrderedSet* tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.subitems];
    [tempSet addObject:value];
    self.subitems = tempSet;
}

सेट को स्व.सुइट पर भेजने से यह सुनिश्चित होगा कि विल / डिडचेंजवैल्यू सूचनाएं भेजी जाती हैं।


आपका कोड स्निपेट सिर्फ वही था जो मुझे इस मुद्दे पर लाने के लिए आवश्यक था। आशा है कि Apple इस मुद्दे को अंततः ठीक कर देगा, लेकिन अभी तक मैंने आपके दृष्टिकोण का उपयोग करने के साथ कोई समस्या नहीं देखी है।
क्रिस्टोफर हुजेन

मुझे यह त्रुटि तब हो रही है जब मैं इस कार्य को कार्यान्वित करने का प्रयास करता हूं .. [__NSArrayI isEqualToSet:]: अपरिचित चयनकर्ता को उदाहरण के लिए भेजा गया ... यह आमतौर पर एक आइटम से होता है जो जारी किया गया है, लेकिन यह नहीं मिल रहा है कि, कोई भी कहां चला सकता है इस मामले में?
डेरेक

@DerekH isEqualToSet एक विधि है जो केवल NSSet के पास है, इसलिए मेरा अनुमान है कि आप NSManagedObject में वापस जाने से पहले एक सूचक को NSArray के रूप में परिवर्तित, निर्मित, या कर रहे हैं, जो कि यदि किसी कारण से isEqualToOrderedSet सेट किया जाना चाहिए, तो यह निर्धारित करने के लिए कि क्या होना चाहिए। यहां तक ​​कि बदलने के लिए या के रूप में छोड़ दिया है।
initJason

3
@ मार्की टेस्टी। सत्यापित। डायनामिक सेटर self.subitems सूचनाएँ भेजता है। तो JLust समाधान सही है।
15

3
यह एक अच्छा उत्तर है, लेकिन यह अक्षम है। आप पूरे ऑर्डर किए गए सेट को कॉपी करें, संशोधित करें और फिर इसे वापस कॉपी करें। प्रभाव केवल ऑर्डर किए गए सेट के लिए एक हिट नहीं है, लेकिन सूचनाएं बाहर भेजी जाती हैं कि हर बार ऑर्डर किए गए सेट को बदल दिया जाता है, इसकी पूरी सामग्री बदल जाती है! यदि इस आदेशित सेट का उपयोग उदाहरण के लिए एक यूआईटेबल के लिए किया जाता है, तो यह अद्यतन करने के लिए गंभीर प्रभाव हो सकता है। मैंने अपने समाधान में वही बताया है जहाँ से त्रुटि आती है और मैंने त्रुटि को दरकिनार करने के लिए एक अधिक कुशल तरीका दिखाया है।
ओवेन गॉडफ्रे

111

मैंने सभी आवश्यक विधियों को लागू करके समाधान में सुधार करने का निर्णय लिया है:

static NSString *const kItemsKey = @"<#property#>";

- (void)insertObject:(<#Type#> *)value in<#Property#>AtIndex:(NSUInteger)idx {
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet insertObject:value atIndex:idx];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)removeObjectFrom<#Property#>AtIndex:(NSUInteger)idx {
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet removeObjectAtIndex:idx];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)insert<#Property#>:(NSArray *)values atIndexes:(NSIndexSet *)indexes {
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet insertObjects:values atIndexes:indexes];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)remove<#Property#>AtIndexes:(NSIndexSet *)indexes {
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet removeObjectsAtIndexes:indexes];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)replaceObjectIn<#Property#>AtIndex:(NSUInteger)idx withObject:(<#Type#> *)value {
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet replaceObjectAtIndex:idx withObject:value];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)replace<#Property#>AtIndexes:(NSIndexSet *)indexes with<#Property#>:(NSArray *)values {
    [self willChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet replaceObjectsAtIndexes:indexes withObjects:values];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)add<#Property#>Object:(<#Type#> *)value {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSUInteger idx = [tmpOrderedSet count];
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    [tmpOrderedSet addObject:value];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)remove<#Property#>Object:(<#Type#> *)value {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSUInteger idx = [tmpOrderedSet indexOfObject:value];
    if (idx != NSNotFound) {
        NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
        [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
        [tmpOrderedSet removeObject:value];
        [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
        [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    }
}

- (void)add<#Property#>:(NSOrderedSet *)values {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    NSUInteger valuesCount = [values count];
    NSUInteger objectsCount = [tmpOrderedSet count];
    for (NSUInteger i = 0; i < valuesCount; ++i) {
        [indexes addIndex:(objectsCount + i)];
    }
    if (valuesCount > 0) {
        [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
        [tmpOrderedSet addObjectsFromArray:[values array]];
        [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
        [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    }
}

- (void)remove<#Property#>:(NSOrderedSet *)values {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    for (id value in values) {
        NSUInteger idx = [tmpOrderedSet indexOfObject:value];
        if (idx != NSNotFound) {
            [indexes addIndex:idx];
        }
    }
    if ([indexes count] > 0) {
        [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
        [tmpOrderedSet removeObjectsAtIndexes:indexes];
        [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
        [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    }
}

1
क्रैश प्रकार क्या है? 'removeObjectFromSubitemsAtIndex' इन सबिटम्स को नहीं हटाता है, वे अभी भी आपके भंडारण में मौजूद हैं, यह सिर्फ वस्तुओं के बीच के रिश्ते को हटाने का तरीका है।
दिमित्री मकारेंको

2
kItemsKey एक स्थिरांक है जिसे KVO विधियों के कॉल में सुविधा के लिए जोड़ा गया था। यह एक आदेशित संबंध का नाम है जिसके लिए आप अपने तरीके लिख रहे हैं।
दिमित्री मकारेंको

1
मुझे लगता है कि यह है। धन्यवाद। लेकिन मेरी समस्या यह है कि इन विधियों का उपयोग करके डेटा को डेटाबेस में सहेजा नहीं जाता है।
Bagusflyer

4
!!!!!!!!! बस कोड की प्रतिलिपि बनाने और विधि के नाम बदलने के लिए, यह पूरी तरह से काम करता है !!! यह सबसे तेज उत्तर है।
फ्लाईपिग

1
यह भयानक है, लेकिन आदेशित सेट की अस्थायी प्रतिलिपि बनाना अनावश्यक है। अपराधी वह है willChangeValueForKey:withSetMutation:usingObjects, जिसे आपने सफलतापूर्वक टाला है। उसके बाद, बस का उपयोग करें [[self primitiveValueForKey:ChildrenKey] unionOrderedSet:values]या [[self primitiveValueForKey:ChildrenKey] minusOrderedSet:values]उचित के रूप में। विवरण के लिए मेरा उत्तर देखें।
ओवेन गॉडफ्रे

38

हां, यह निश्चित रूप से एक कोर डेटा बग है। मैंने कुछ समय पहले एक ओबीजीसी-रनटाइम-आधारित फिक्स लिखा था, लेकिन मुझे लगा कि यह जल्द ही ठीक हो जाएगा। फिर भी, ऐसी कोई किस्मत नहीं, इसलिए मैंने इसे GHHub पर KCOrderedAccessorFix के रूप में पोस्ट किया । अपनी सभी संस्थाओं पर समस्या के आसपास काम करें:

[managedObjectModel kc_generateOrderedSetAccessors];

विशेष रूप से एक इकाई:

[managedObjectModel kc_generateOrderedSetAccessorsForEntity:entity];

या सिर्फ एक रिश्ते के लिए:

[managedObjectModel kc_generateOrderedSetAccessorsForRelationship:relationship];

मुझे आश्चर्य है कि क्या यह एप्पल से वास्तविक फिक्स के साथ संघर्ष करेगा या नहीं?
tia

3
यह एप्पल के फिक्स के साथ संघर्ष नहीं करना चाहिए, क्योंकि इसका उद्देश्य एप्पल के कार्यान्वयन को खत्म करने से कोई फर्क नहीं पड़ता है। जब / यदि यह वास्तव में Apple द्वारा तय किया गया है, तो शायद मैं एक - (BOOL)kc_needsOrderedSetAccessorFix;ऐसी चीज या कुछ जोड़ूंगा जो फाउंडेशन / आईओएस संस्करण की जांच करता है।
स्टर्लिंग आर्चर

2
कोकोपोड्स मास्टर रेपो में KCOrderedAccessorFix.podspec पहले से ही है। तो इसे अपनी परियोजनाओं से जोड़ने के लिए आप बस अपने पॉडफाइल में "पॉड 'KCOrderedAccessorFix" जोड़ सकते हैं
एंटोन माटोसोव

आईओएस 8 के साथ इसके कुछ मुद्दे थे (गलत तरीके से हस्ताक्षर के लिए objc_msg_send)
एनएसटीजे

IOS9 पर यह काम करता है, अच्छा काम! यह अब तक का सबसे अच्छा समाधान है, अपने कोड में कुछ भी बदलने की आवश्यकता नहीं है!
बोरझ

32

मैं कॉपी करने के बजाय NSObject में एक्सेसर का उपयोग करने का सुझाव देता हूं ताकि रिश्तों के NSMutableOrderedSet तक पहुंच प्राप्त कर सके।

- (void)addSubitemsObject:(SubItem *)value {
      NSMutableOrderedSet* tempSet = [self mutableOrderedSetValueForKey:@"subitems"];
      [tempSet addObject:value];
 }

उदाहरण के लिए iOS v5.0 के लिए कोर डेटा रिलीज़ नोट्स इसका उल्लेख करते हैं।

एक छोटी परीक्षा में इसने मेरे आवेदन में काम किया।


1
आसानी से शाब्दिक तार को रिफलेक्टर नहीं किया जा सकता। यदि आप कोड का उपयोग करते हैं तो कंपाइलर self.subitems की जाँच कर सकता है।
logancautrell

1
@logancautrell हाँ यह सही है। यह विशिष्ट उपयोग के मामले की प्राथमिकता पर निर्भर करता है। सामान्य तौर पर मैं इस मामले में विशेष रूप से संसाधनों को बचाने पर ध्यान केंद्रित करता हूं क्योंकि यह सिर्फ एक समाधान था।
Stephan

2
शाब्दिक स्ट्रिंग को प्रतिस्थापित किया जा सकता है, NSStringFromSelector(@selector(subitems))हालांकि :)
Ja Julck

17

मैंने बग को ट्रैक कर लिया है। इसमें होता है willChangeValueForKey:withSetMutation:usingObjects:

यह कॉल सूचनाओं की एक श्रृंखला को बंद करता है, जिसे ट्रैक करना मुश्किल हो सकता है, और निश्चित रूप से एक उत्तरदाता के परिवर्तन से दूसरे के लिए निहितार्थ हो सकते हैं, जिस पर मुझे संदेह है कि Apple ने कुछ नहीं किया है।

हालाँकि, यह सेट में ठीक है और इसके केवल सेट ऑपरेशन एक ऑर्डरडैट पर जो कि खराबी है। इसका मतलब है कि केवल चार तरीके हैं जिन्हें बदलने की आवश्यकता है। इसलिए, मैंने जो भी किया वह सेट ऑपरेशंस को उनके समकक्ष एरे ऑपरेशंस में बदल दिया। ये पूरी तरह से और न्यूनतम (लेकिन आवश्यक) ओवरहेड्स का काम करते हैं।

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

- (void)addChildrenObject:(BAFinancialItem *)value {
    if ([self.children containsObject:value]) {
        return;
    }
    NSIndexSet * indexSet = [NSIndexSet indexSetWithIndex:self.children.count];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
    [[self primitiveValueForKey:ChildrenKey] addObject:value];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
}

- (void)removeChildrenObject:(BAFinancialItem *)value {
    if (![self.children containsObject:value]) {
        return;
    }
    NSIndexSet * indexSet = [NSIndexSet indexSetWithIndex:[self.children indexOfObject:value]];
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
    [[self primitiveValueForKey:ChildrenKey] removeObject:value];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
}

- (void)addChildren:(NSOrderedSet *)values {
    if ([values isSubsetOfOrderedSet:self.children]) {
        return;
    }
    NSIndexSet * indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(self.children.count, values.count)];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
    [[self primitiveValueForKey:ChildrenKey] unionOrderedSet:values];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
}

- (void)removeChildren:(NSOrderedSet *)values {
    if (![self.children intersectsOrderedSet:values]) {
        return;
    }
    NSIndexSet * indexSet = [self.children indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        return [values containsObject:obj];
    }];
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
    [[self primitiveValueForKey:ChildrenKey] minusOrderedSet:values];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
}

बेशक, एक आसान उपाय है। यह इस प्रकार है;

- (void)addChildrenObject:(BAFinancialItem *)value {
    if ([self.children containsObject:value]) {
        return;
    }
    [self insertObject:value inChildrenAtIndex:self.children.count];
}

- (void)removeChildrenObject:(BAFinancialItem *)value {
    if (![self.children containsObject:value]) {
        return;
    }
    [self removeObjectFromChildrenAtIndex:[self.children indexOfObject:value]];
}

- (void)addChildren:(NSOrderedSet *)values {
    if ([values isSubsetOfOrderedSet:self.children]) {
        return;
    }
    [self insertChildren:values atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(self.children.count, values.count)]];
}

- (void)removeChildren:(NSOrderedSet *)values {
    if (![self.children intersectsOrderedSet:values]) {
        return;
    }
    [self removeChildrenAtIndexes:[self.children indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        return [values containsObject:obj];
    }]];
}

बहुत बुरा लगता है कि हर कोई इस जवाब को नजरअंदाज कर दिया है, निश्चित रूप से सबसे अच्छा समाधान की तरह लगता है।
जॉर्ज

यह समाधान स्थानीय सेट बनाने के लिए orderSetWithOrderedSet का उपयोग करने वालों की तुलना में बेहतर प्रदर्शन है। जब आपके पास बड़े डेटा सेट होते हैं तो एक बड़ा ओवरहेड होता है। आसान समाधान केवल दिखाए गए तरीकों के साथ प्रारंभिक एक का एक परिष्कृत संस्करण प्रतीत होता है।
डेविड पेटीग्रे

1
मुझे अभी भी AddChildren में एक दुर्घटना दिखाई दे रही है: *** अपवादित अपवाद 'NSInvalidArgumentException', कारण के कारण ऐप समाप्त हो रहा है: कारण: '- [TrackHistory InsertTrackpoint: atIndexes:]: 0x1702b1b20' के लिए भेजा गया अज्ञात पहचानकर्ता
विक्टर बोगडान

@OwenGodfrey आसान समाधान के लिए, आप इन विधियों को कहां लागू कर रहे हैं? मुझे एक अपवाद मिल रहा है: [पैरेंट इन्सर्टऑबजेक्ट: इनहिल्ड्रेनएटइंडेक्स:] c०x१0000ac०००००००४ .० इंस्टेंस पर भेजे गए गैर-मान्यताप्राप्त चयनकर्ता।
डालमज़ियो

आपका चर "पी" के साथ "पेरेंट" है? क्या इसका मतलब है कि आप कक्षा को "जनक" कह रहे हैं, या क्या आपके पास "माता-पिता" नामक एक उदाहरण चर है? अगर मेरी कक्षा अभिभावक है, तो मैंने इस तरीके को माता-पिता के तल पर लागू किया है, लेकिन आपको इसे एक उदाहरण पर कॉल करने की आवश्यकता होगी, जिसे संभवतः "पैरेंट" नाम दिया जाएगा "लोअरकेस" के साथ, क्योंकि ये क्लास के तरीके नहीं हैं ।
ओवेन गॉडफ्रे

10

कई संबंध के लिए एप्पल डॉक्स का कहना है: आप प्रॉक्सी परिवर्तनशील सेट का उपयोग करना चाहिए या का उपयोग कर सेट का आदेश दिया

NSMutableOrderedSet * set = [managedObject mutableOrderedSetValueForKey:@"toManyRelation"];

इस सेट को संशोधित करने से आपके प्रबंधित ऑब्जेक्ट में संबंध जुड़ेंगे या हटेंगे। [] या के साथ, चाहे अभिगमक का उपयोग करके सेट किए गए उत्परिवर्तित एक्सेस पर पहुँचना। अंकन गलत है और विफल हो जाएगा।


3
निष्पक्ष होने के लिए, डॉक्स यह भी कहते हैं: "या स्वचालित रूप से उत्पन्न संबंध उत्परिवर्ती तरीकों में से एक (डायनामिक-जनरेटेड एक्सेसर मेथड्स देखें):"
मैट

ठीक है ठीक है ... तुम सही हो। ठीक है, तो हम कहते हैं कि यह सबसे सरल तरीका है ...
निकोलस मंज़िनी

9

उसी त्रुटि को प्राप्त किया, @LeeIII समाधान ने मेरे लिए काम किया (धन्यवाद!)। मेरा सुझाव है कि इसे थोड़ा संशोधित करें:

  • नई पद्धति को संग्रहीत करने के लिए उद्देश्य-सी श्रेणी का उपयोग करें (इसलिए यदि आइटम दोबारा उत्पन्न होता है तो हम अपना तरीका नहीं खोते)
  • जांचें कि क्या हमारे पास पहले से ही परिवर्तनशील सेट है

की सामग्री Item+category.m:

#import "Item+category.h"

@implementation Item (category)

- (void)addSubitemsObject:(SubItem *)value {
    if ([self.subitems isKindOfClass:[NSMutableOrderedSet class]]) {
        [(NSMutableOrderedSet *)self.subitems addObject:value];
    } else {
        NSMutableOrderedSet* tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.subitems];
        [tempSet addObject:value];
        self.subitems = tempSet;
    }
}

@end

इस कोड को श्रेणी में स्थानांतरित करने के लिए अच्छा बिंदु। लेकिन फिर भी हमें वसीयत के साथ वास्तविक ऐड / रिमूव को हटाना होगा।
व्लादिमीर Shutyuk

8

यदि आप mogenerator का उपयोग कर रहे हैं, तो इसके बजाय

[parentObject add<Child>sObject:childObject];

बस उपयोग करें:

[[parent object <child>sSet] addObject:childObject];

क्योंकि mogenerator अतिरिक्त कोड का ध्यान रखता है जो आपको अन्यथा लिखना होता है और बस अंतर्निहित सेट ऑब्जेक्ट तक पहुंच की अनुमति देता है।
12αrΚhικ

ऐसा लगता है कि एक ठीक तरह सिर्फ किया गया है कि इसका मतलब है mogenerator को सही निकायों ... उत्पन्न होगा github.com/dmakarenko/mogenerator/commit/...
मिश्रित

1
मैं उपयोग कर रहा हूँ, mogeneratorलेकिन मेरे पास अभी भी बग है।
कोला

7

व्यक्तिगत रूप से मैंने अभी कॉल को कोरडैटा जनरेटेड मेथड्स के साथ डायरेक्ट कॉल के तरीके के रूप में प्रतिस्थापित किया है जैसा कि @Pepep द्वारा दूसरे समाधान में उल्लिखित है:

NSMutableOrderedSet* tempSet = [self mutableOrderedSetValueForKey:@"subitems"];
      [tempSet addObject:value];
[tempSet addObject:value];

यह उन श्रेणियों की आवश्यकता को हटा देता है जो बाद में बग के ठीक होने पर Apple से समाधान के साथ उत्पन्न कोड में संघर्ष कर सकती हैं।

यह इसे करने का आधिकारिक तरीका होने का जोड़ा प्लस है!


यह निम्नलिखित त्रुटि देता है: '[<CLASS 0x20886d10> valueForUndefinedKey:]: यह वर्ग प्रमुख उप-कोड के लिए महत्वपूर्ण मूल्य कोडिंग-अनुरूप नहीं है।'
jmstone617

हालांकि यह अभी भी मुझे कोई अंत नहीं है कि यह Apple के ज्ञात मुद्दों में सूचीबद्ध नहीं है (मैंने जाहिरा तौर पर निरर्थक इशारे के लिए एक रडार खोला है), यह समाधान मेरे लिए निर्दोष रूप से काम किया है।
स्कॉट कोर्सेडेन

काश मैंने यह जवाब पहले देखा होता; जब तक मैंने हाल ही में कुछ खुदाई की थी और तब तक लागू किया गया था, जब तक कि आपके पास यहां क्या है :)
Ja͢ck

addObject:दो बार क्यों कहा जाता है?
जेसन मूर

5

ऐसा लगता है कि यदि आप बच्चे को माता-पिता को बच्चे के साथ जोड़ते हैं और दुर्घटनाग्रस्त हुए बिना काम नहीं करते हैं।

तो अगर तुम करते हो:

[child setParent:parent]

के बजाय

[parent setChildObects:child]

यह काम करना चाहिए, कम से कम यह iOS 7 पर काम करता है और रिश्ते के साथ कोई समस्या नहीं थी।


1
बहुत अच्छा नहीं करता है जब दोनों पक्ष कई हैं। फिर कोई स्पष्ट अभिभावक-बच्चा संबंध नहीं है।
फतुहोकू

3

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

Item *item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
item.name = @"FirstItem";

SubItem *subItem = [NSEntityDescription insertNewObjectForEntityForName:@"SubItem" inManagedObjectContext:self.managedObjectContext];

//[item addSubitemsObject:subItem];
subItem.parentItem = item;

इसका प्रभाव यह है कि यह सेब के अपने कोड का उपयोग करता है और यह सरल और साफ है। इसके अलावा, सेट को स्वचालित रूप से जोड़ा जाता है, और सभी पर्यवेक्षक अपडेट किए जाते हैं। कोई दिक्कत नहीं है।


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

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

वाह! आखिरकार!!! धन्यवाद! (अपने अन्य कोड की कोशिश की, लेकिन त्रुटियां मिलीं, उस गलत प्रकार के बारे में कुछ भेजा गया था [self didChange: NSKeyValueChangeInsertion valuesAtIndexes: indexSet forKey: ChildrenKey];)
लियोनार्ड

3

मैं बस इस मुद्दे पर बेईमानी से गिर गया, और इसे बहुत सरल कार्यान्वयन का उपयोग करके हल किया, जो यहां उल्लिखित है। मैं केवल NSManagedObjectउपवर्गों का उपयोग न करने पर रिश्तों से निपटने के लिए उपलब्ध तरीकों का उपयोग करता हूं ।

एक NSOrderedSetरिश्ते में एक इकाई डालने के लिए एक उदाहरण कार्यान्वयन इस तरह दिखेगा:

- (void)addAddress:(Address *)address
{
    if ([self.addresses containsObject:address]) {
        return;
    }
    // Use NSManagedObject's methods for inserting an object
    [[self mutableOrderedSetValueForKey:@"addresses"] addObject:address];
}

यह पूरी तरह से काम करता है, और इससे पहले कि मैं NSManagedObjectउपवर्गों में जाने से पहले मैं क्या उपयोग कर रहा था ।


3

XCode 7 के साथ ऑब्जेक्टिव-सी से स्विफ्ट 2 के लिए प्रोजेक्ट माइग्रेट करते समय यह समस्या मेरे साथ हुई । वह परियोजना काम करती थी, और एक अच्छे कारण के लिए: मैं MOGenerator का उपयोग कर रहा था जिसमें इस बग को ठीक करने के लिए प्रतिस्थापन विधियाँ थीं। लेकिन सभी तरीकों को बदलने की आवश्यकता नहीं होती है।

तो यहाँ एक उदाहरण वर्ग के साथ पूरा समाधान है, जितना संभव हो सके डिफ़ॉल्ट एक्सेसर्स पर भरोसा करना।

मान लें कि हमारे पास ऑर्डर किए गए आइटम के साथ एक सूची है

पहली जीत अगर आपके पास एक-से-कई संबंध हैं, तो सबसे आसान काम करना है:

item.list = list

के बजाय

list.addItemsObject(item)

अब, यदि यह विकल्प नहीं है , तो यहां आप क्या कर सकते हैं:

// Extension created from your DataModel by selecting it and
// clicking on "Editor > Create NSManagedObject subclass…"

extension List {
  @NSManaged var items: NSOrderedSet?
}

class List

  // Those two methods work out of the box for free, relying on
  // Core Data's KVC accessors, you just have to declare them
  // See release note 17583057 https://developer.apple.com/library/prerelease/tvos/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc7_release_notes.html
  @NSManaged func removeItemsObject(item: Item)
  @NSManaged func removeItems(items: NSOrderedSet)

  // The following two methods usually work too, but not for NSOrderedSet
  // @NSManaged func addItemsObject(item: Item)
  // @NSManaged func addItems(items: NSOrderedSet)

  // So we'll replace them with theses

  // A mutable computed property
  var itemsSet: NSMutableOrderedSet {
    willAccessValueForKey("items")
    let result = mutableOrderedSetValueForKey("items")
    didAccessValueForKey("items")
    return result
  }

  func addItemsObject(value: Item) {
    itemsSet.addObject(value)
  }

  func addItems(value: NSOrderedSet) {
    itemsSet.unionOrderedSet(value)
  }
end

बेशक, यदि आप ऑब्जेक्टिव-सी का उपयोग कर रहे हैं, तो आप ठीक वही काम कर सकते हैं क्योंकि यह वह जगह है जहां मुझे पहले स्थान पर विचार मिला है :)


3

मैं मानता हूँ कि शायद यहाँ एक बग है। मैंने NSMutableOrderedSet में सही तरीके से जोड़ने के लिए ऐड ऑब्जेक्ट> सेटर के कार्यान्वयन को संशोधित किया है।

- (void)addSubitemsObject:(SubItem *)value {
     NSMutableOrderedSet* tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.subitems];
     [tempSet addObject:value];
     self.subitems = tempSet;
}

सेट को स्व.सुइट पर भेजने से यह सुनिश्चित होगा कि विल / डिडचेंजवैल्यू सूचनाएं> भेजी जाती हैं।

Leelll, क्या आप सुनिश्चित हैं कि NSMutableOrderedSet के ऐसे कस्टम सेटअप के बाद उस सेट में संग्रहीत मान को कोरडेटा द्वारा डेटाबेस में सही ढंग से सहेजा जाएगा? मैंने इसकी जाँच नहीं की, लेकिन ऐसा लगता है कि CoreData NSOrderedSet के बारे में कुछ नहीं जानता है और NSSet से कई संबंध कंटेनर के रूप में अपेक्षा करता है।


CoreData के लिए NSOrderedSet ऑब्जेक्ट वापस करने या लेने के लिए, कई शर्तों को पूरा करना होगा क्योंकि यह शुरू किया गया प्रश्न दिखाया गया है। सबसे आम गलतियाँ जब मैं देखता हूं कि मेरे कोड को साझा करने वाले लोग एक डेवलपर रहे हैं जो शेर नहीं चला रहे हैं। NSOrderedSets का ढांचा स्नोलेयोपार्ड पर उपलब्ध नहीं है। लेकिन हां, मैंने इसे विफल नहीं देखा है, हालांकि मुझे यकीन नहीं है कि यह प्रदर्शन पर सबसे अच्छा है। मुझे लगता है कि यह पूरा सेट लेता है और वांछित रिकॉर्ड डालने के बजाय इसे प्रतिस्थापित करता है।
initJason

2

मुझे लगता है कि हर कोई वास्तविक समस्या को याद कर रहा है। यह एक्सेसर के तरीकों में नहीं है, बल्कि इस तथ्य में है कि NSOrderedSetउप-वर्ग नहीं है NSSet। तो जब -interSectsSet:एक आदेश सेट के साथ कहा जाता है तो यह तर्क विफल हो जाता है।

NSOrderedSet* setA = [NSOrderedSet orderedSetWithObjects:@"A",@"B",@"C",nil];
NSSet* setB = [NSSet setWithObjects:@"C",@"D", nil];

 [setB intersectsSet:setA];

के साथ विफल रहता है *** -[NSSet intersectsSet:]: set argument is not an NSSet

ऐसा लगता है कि फिक्स को सेट ऑपरेटरों के कार्यान्वयन को बदलना है ताकि वे प्रकारों को पारदर्शी तरीके से संभाल सकें। कोई कारण नहीं है कि एक -intersectsSet:या तो एक आदेश या अनियंत्रित सेट के साथ काम करना चाहिए।

परिवर्तन सूचना में अपवाद होता है। संभवतः उस कोड में जो उल्टे संबंध को संभालता है। चूंकि यह केवल तभी होता है जब मैं एक व्युत्क्रम संबंध स्थापित करता हूं।

निम्नलिखित ने मेरे लिए चाल चली

@implementation MF_NSOrderedSetFixes

+ (void) fixSetMethods
{
    NSArray* classes = [NSArray arrayWithObjects:@"NSSet", @"NSMutableSet", @"NSOrderedSet", @"NSMutableOrderedSet",nil];

    [classes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSString* name = obj;
        Class aClass = objc_lookUpClass([name UTF8String]);
        [MF_NSOrderedSetFixes fixMethodWithSetArgument:@selector(intersectsSet:) forClass:aClass];
        [MF_NSOrderedSetFixes fixMethodWithSetArgument:@selector(isSubsetOfSet:) forClass:aClass];
    }];
}

typedef BOOL (*BoolNSetIMP)(id _s,SEL sel, NSSet*);

/*
    Works for all methods of type - (BOOL) method:(NSSet*) aSet
*/
+ (void) fixMethodWithSetArgument:(SEL) aSel forClass:(Class) aClass 
{
    /* Check that class actually implements method first */
    /* can't use get_classInstanceMethod() since it checks superclass */
    unsigned int count,i;
    Method method = NULL;
    Method* methods = class_copyMethodList(aClass, &count);
    if(methods) {
        for(i=0;i<count;i++) {
            if(method_getName(methods[i])==aSel) {
                method = methods[i];
            }
        }
        free(methods);
    }
    if(!method) {
        return;
    }

   // Get old implementation
   BoolNSetIMP originalImp  = (BoolNSetIMP) method_getImplementation(method);
   IMP newImp = imp_implementationWithBlock(^BOOL(NSSet *_s, NSSet *otherSet) {
        if([otherSet isKindOfClass:[NSOrderedSet class]]) {
            otherSet = [(NSOrderedSet*)otherSet set];
        }
        // Call original implementation
        return originalImp(_s,aSel,otherSet);
    });
    method_setImplementation(method, newImp);
}
@end

2

मुझे सिर्फ स्विफ्ट (Xcode 6.1.1) में समस्या हुई।

उत्तर यह नहीं था कि आपके NSManagedObject उपवर्गों में कोई भी मैथड या एडिशनल थिंग्स शामिल नहीं है। मुझे लगता है कि यह एक कंपाइलर की गलती है। बहुत अजीब बग ।।

आशा है ये मदद करेगा ..


3
इसलिए, यदि मैं अन्य सुधारों को लागू नहीं कर सकता, तो मुझे इसे ठीक करने के लिए क्या करना चाहिए?
बेन लेगिएरो

2

मैंने उलटा नो इनवर्स के सेट से इस समस्या को हल किया, मुझे पता नहीं क्यों, शायद वहाँ Apple Bug है।यहां छवि विवरण दर्ज करें


1

मेरे पास "सबिटम्स" के बजाय "सिग्नल" नामक आइटम के साथ एक ही स्थिति है। टेम्प्लेट के साथ समाधान मेरे परीक्षण में काम करता है। इसके अलावा, मुझे हटाने की विधि के साथ एक समस्या थी: विधि। यह ओवरराइड काम करने लगता है:

- (void)removeSignals:(NSOrderedSet *)values {
    NSMutableOrderedSet* tempset = [NSMutableOrderedSet orderedSetWithOrderedSet:self.signals];
    for (Signal* aSignal in values) {
        [tempset removeObject:aSignal];
    }
    self.signals = tempset;
}

यदि ऐसा करने का कोई बेहतर तरीका है, तो कृपया मुझे बताएं। मेरे मान इनपुट 10 -20 से अधिक आइटम कभी नहीं हैं, इसलिए प्रदर्शन बहुत चिंता का विषय नहीं है - फिर भी कृपया प्रासंगिक कुछ भी इंगित करें।

धन्यवाद,

डेमियन


1

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

मैं एक नया मॉडल संस्करण जोड़ रहा था, और मौजूदा मॉडल में कुछ रिश्ते जोड़े, और हेडर फ़ाइल में जोड़ें * ऑब्जेक्ट विधियों को स्वयं परिभाषित किया। जब मैंने उन्हें फोन करने की कोशिश की, तो मुझे ऊपर त्रुटि मिली।

अपने मॉडलों की समीक्षा करने के बाद, मुझे एहसास हुआ कि मैं "टू-कई रिलेशनशिप" चेकबॉक्स की जांच करना भूल गया था।

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


1

मुझे इस बग के लिए एक फिक्स मिला जो मेरे लिए काम करता है। मैं इसे प्रतिस्थापित करता हूं:

[item addSubitemsObject:subItem];

इसके साथ:

item.subitemsObject = subItem;

1

SWIFT में सही उत्तर का बेहतर संस्करण

var tempSet = NSMutableOrderedSet()
if parent!.subItems != nil {
    tempSet = NSMutableOrderedSet(orderedSet: parent!.subItems!)
}

tempSet.add(newItem)
parent!.subItems = tempSet

0

मैंने पाया कि लीथियो ने इस विधि का उपयोग किया, लेकिन प्रोफाइलिंग में पाया गया कि यह बहुत धीमी गति से चल रही थी। 1000 आइटम को पार्स करने में 15 सेकंड का समय लगा। रिश्ते को जोड़ने के लिए कोड को टिप्पणी करते हुए 15 सेकंड 2 सेकंड में बदल गया।

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

@property (nonatomic, retain) NSMutableArray* tempItems;
 ....
@synthesize tempItems = _tempItems;
 ....

- (void) addItemsObject:(KDItem *)value 
{
    if (!_tempItems) {
        self.tempItems = [NSMutableArray arrayWithCapacity:500];
    }
    [_tempItems addObject:value];
}

// Call this when you have added all the relationships
- (void) commitRelationships 
{
    if (_tempItems) {
        self.items = [NSOrderedSet orderedSetWithArray:self.tempItems];
        self.tempItems = nil;
    }
}

मुझे आशा है कि यह किसी और की मदद करेगा!


0

रॉबर्ट,

मैं मानता हूं कि आपका जवाब इसके लिए काम करेगा, लेकिन ध्यान रखें कि रिश्ते के लिए पहले से ही मूल्यों का एक पूरा सेट जोड़ने के लिए एक स्वचालित रूप से बनाई गई विधि है। Apple का दस्तावेज़ीकरण ( जैसा कि "टू-कई रिलेशनशिप्स" सेक्शन के तहत यहां देखा गया है या "कस्टम टू-रिलेशनशिप एक्सेसर मेथड्स सेक्शन" सेक्शन के तहत) उन्हें इस तरह से लागू करता है:

- (void)addEmployees:(NSSet *)value
{
[self willChangeValueForKey:@"employees"
      withSetMutation:NSKeyValueUnionSetMutation
      usingObjects:value];
[[self primitiveEmployees] unionSet:value];
[self didChangeValueForKey:@"employees"
      withSetMutation:NSKeyValueUnionSetMutation
      usingObjects:value];
}

- (void)removeEmployees:(NSSet *)value
{
[self willChangeValueForKey:@"employees"
      withSetMutation:NSKeyValueMinusSetMutation
      usingObjects:value];
[[self primitiveEmployees] minusSet:value];
[self didChangeValueForKey:@"employees"
      withSetMutation:NSKeyValueMinusSetMutation
      usingObjects:value];
}

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


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.