Не удалось вызвать назначенный инициализатор в классе NSManagedObject ‘Item’

#objective-c #core-data #nsmanagedobject

#objective-c #core-data #nsmanagedobject

Вопрос:

Я использую core-data для добавления / удаления ‘Items’ (NSManagedObject) в модель.

Однако я получаю ошибку в названии:

Код: Не удалось вызвать назначенный инициализатор в классе NSManagedObject ‘Item’ Я был бы очень признателен, если бы вы могли сказать мне, где я ошибаюсь. Я предполагаю, что проблема связана с инициализацией Item.

RootViewController.m

 - (void)AddNew {
    CDManager *manager = [[CDManager alloc] initWithManagedObjectContext:[self managedObjectContext] andDelegate:self];
    [manager addNewObject:[Item itemWithDescription:@"testing" dateSet:[NSDate date] fullfillBy:[NSDate date]]];
    [manager release];
}
  

CDManager.m

 - (id) initWithManagedObjectContext:(NSManagedObjectContext *)context andDelegate:(id<CDManagerDelegateProtocol>)delegate {
    if ((self = [super init])) {
        [self setDelegate:delegate];
        [self setContext:context];
        [self setItems:[[NSMutableArray alloc] init]];
        [self updateItems];
    }
    return self;
}

- (void)addNewObject:(Item *)item {
    NSManagedObjectContext *context = _context;
    Item *items = [NSEntityDescription
                            insertNewObjectForEntityForName:@"Item" 
                            inManagedObjectContext:_context];
    [items setDateSet:[item dateSet]];
    [items setDateToFullfill:[item dateToFullfill]];
    [items setItemDescription:[item itemDescription]];
    NSError *error;
    if (![context save:amp;error]) {
        NSLog(@"Couldn't save due to : %@", [error localizedDescription]);
    }
    [_delegate manager:self didAddNewItem:items];
    [self update];
}
  

Item.m

 static Item *shared = nil;
@implementation Item
......

  (Item *)itemWithDescription:(NSString *)d dateSet:(NSDate *)date fullfillBy:(NSDate *)dates {
    @synchronized(shared) {
        if (!shared || shared == NULL) {
            shared = [[Item alloc] init];
        }
        [shared setItemDescription:d];
        [shared setDateSet:date];
        [shared setDateToFullfill:dates];
        return shared;
    }
}
  

Ответ №1:

Item Класс определен как синглтон. Для одноэлементных подклассов NSManagedObject не предусмотрено. Контекст не поймет, как с этим справиться.

В этом коде очень мало смысла. Здесь вы инициализируете одноэлементный Item объект:

 [manager addNewObject:[Item itemWithDescription:@"testing" dateSet:[NSDate date] fullfillBy:[NSDate date]]]
  

… но вы не присоединяете его к контексту перед передачей в addNewObject: метод. В свою очередь, этот метод создает другой экземпляр Item, а затем заполняет его значениями предполагаемого синглтона. Почему? Если ваш одноэлементный код действительно работает, каждый раз, когда вы создаете экземпляр Item, вы будете получать тот же объект обратно. Какой смысл создавать еще одну ссылку на синглтон и устанавливать его собственные значения для себя. Если одноэлементный код не работает, зачем вообще использовать одноэлементный?

Именно из-за такого использования синглтоны имеют такую плохую репутацию. Не используйте синглтоны, если у вас нет большого опыта работы с ними, и они абсолютно необходимы. В этом коде нет ничего, что указывало бы на то, что вам действительно нужен синглтон, и Core Data определенно их не любит.

Комментарии:

1. Я переписал метод initWithEntity … и удалил синглтон, и он работает отлично. Спасибо за вашу помощь.

Ответ №2:

Может быть, вы делаете что-то вроде

 Item * items = [[Item alloc]initWithEntity:[NSEntityDescription entityForName:@"Item" inManagedObjectContext:context]insertIntoManagedObjectContext:context];
  

Редактировать —

потому что вы не вызываете хороший метод инициализации объекта NSManaged в своем пользовательском методе инициализации. вы также могли бы очистить это до этого, чтобы взять контекст, а затем вызвать initWithEntity … в super там.