在NSOrderedSet生成的訪問器中引發異常

本文翻譯自:Exception thrown in NSOrderedSet generated accessors

On my Lion app, I have this data model: 在我的Lion應用程序上,我具有以下數據模型:

在此處輸入圖片說明

The relationship subitems inside Item is ordered . Item的關係subitems Item 是有序的

Xcode 4.1 (build 4B110) has created for me the file Item.h , Item.m , SubItem.h and SubItem.h . Xcode 4.1(內部版本4B110)爲我創建了文件Item.hItem.mSubItem.hSubItem.h

Here is the content (autogenerated) of Item.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

And here is the content (autogenerated) of Item.m : 這是Item.m的內容(自動生成):

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

@implementation Item

@dynamic name;
@dynamic subitems;

@end

As you can see, the class Item offers a method called addSubitemsObject: . 如您所見, Item類提供了一個名爲addSubitemsObject:的方法。 Unfortunately, when trying to use it in this way: 不幸的是,當嘗試以這種方式使用它時:

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

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

[item addSubitemsObject:subItem];

this error appear: 出現此錯誤:

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

Can you help me? 你能幫助我嗎?

Update: 更新:

After just 1,787 days from my bug report, today (August 1, 2016) Apple wrote me this: "Please verify this issue with the latest iOS 10 beta build and update your bug report at bugreport.apple.com with your results." 從我的錯誤報告發出1,787天后,今天(2016年8月1日),Apple給我寫了這句話: “請使用最新的iOS 10 beta版本驗證此問題,並在bugreport.apple.com上更新您的錯誤報告並提供結果。” . Let's hope this is the right time :) 我們希望這是正確的時機:)


#1樓

參考:https://stackoom.com/question/UzHz/在NSOrderedSet生成的訪問器中引發異常


#2樓

I found using the method by LeeIII worked, but on profiling found it was drastically slow. 我發現使用LeeIII的方法行得通,但是在進行分析時發現它非常慢。 It took 15 seconds to parse 1000 items. 解析1000個項目花了15秒。 Commenting out the code to add the relationship turned 15 seconds into 2 seconds. 註釋掉添加關係的代碼,將15秒變成2秒。

My workaround (which is faster but much more ugly) involves creating a temporary mutable array then copying into the ordered set when all the parsing is done. 我的解決方法(速度更快但更難看)包括創建一個臨時可變數組,然後在完成所有解析後複製到有序集合中。 (this is only a performance win if you are going to add many relationships). (如果要添加許多關係,這只是性能上的勝利)。

@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;
    }
}

I hope this help someone else! 希望對別人有幫助!


#3樓

Robert, 羅伯特

I agree your answer will work for this, but keep in mind that there is an automatically created method for adding a whole set of values to a relationship already. 我同意您的答案可以解決此問題,但是請記住,已經有一種自動創建的方法,用於向關係中添加整套值。 Apple's Documentation ( as seen here under the "To-many Relationships" section or here under the "Custom To-Many Relationship Accessor Methods" section) implements them this way: 蘋果公司的文件( 如這裏看到在“一對多關係”一節或在這裏實現它們這種方式下的“自定義一對多關係存取方法”部分):

- (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];
}

You could easily compile your set of relationships outside of core data and then add them all at once using this method. 您可以輕鬆地在覈心數據之外編譯一組關係,然後使用此方法一次將其全部添加。 It might be less ugly than the method you suggested ;) 它可能不如您建議的方法難看 ;)


#4樓

Personally I have just replaced the calls to the CoreData generated methods with direct calls to the method as outlined in another solution by @Stephan: 我個人剛剛將對CoreData生成的方法的調用替換爲對方法的直接調用,如@Stephan在另一個解決方案中所述:

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

This removes the need for categories that might later conflict with a solution from Apple to the generated code when the bug is fixed. 修復了錯誤之後,無需使用以後可能與Apple的解決方案相沖突的類別。

This has the added plus of being the official way to do it! 這是作爲官方方法的額外好處!


#5樓

If you are using mogenerator, then instead of 如果您使用的是發電機,則代替

[parentObject add<Child>sObject:childObject];

simply use: 只需使用:

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

#6樓

I have had the same problem, but only when I tried something different to what I had been doing. 我遇到了同樣的問題,但是隻有當我嘗試了與自己所做的不同的事情時。 I can't see the code for subItem, but I will assume that it has a reverse link to item. 我看不到subItem的代碼,但我將假定它具有指向項目的反向鏈接。 Lets call this reveres link, "parentItem", then the easiest solution is this: 讓我們稱其爲尊敬的鏈接“ 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;

The effect is that it makes use of apple's own code and it is simple and clean. 效果是它利用了蘋果自己的代碼,並且簡單幹淨。 In addition, the set is automatically added to, and all observers are updated. 此外,該集會自動添加到其中,並且所有觀察者都會更新。 No problem. 沒問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章