Основные данные: `EXC_BAD_ACCESS` при доступе к объектам в отношениях - PullRequest
1 голос
/ 04 июля 2011

У меня есть отношение отображения один ко многим с соответствием имени и подачей.

match <-->> innings
  • match имеет имя поля, идентификатор и т. Д.
  • innings имеет номер поля.

Я могу получить match свойства.Я создаю новый матч в MatchList в TableListController.Я вижу данные для Match и innings доступны в таблице.Теперь я щелкаю строку, созданную в таблице.

Но когда я делаю [match matchinnings],, я получаю NSSet* inningSet.Я могу получить два объекта inningA и inningB от inningSet.Когда я пытаюсь вызвать [inningA number], я получаю сообщение об ошибке.

Ниже приведен мой метод NSFetchResultsController:

- (NSFetchedResultsController *)fetchedResultsController {
    // Set up the fetched results controller if needed.
    //NSLog(@"Inside fetchResultsController ");
    if (fetchedResultsController == nil) {
        // Create the fetch request for the entity.
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        [fetchRequest setReturnsObjectsAsFaults:NO];
        // Edit the entity name as appropriate.
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Match" inManagedObjectContext:managedObjectContext];
        [fetchRequest setEntity:entity];
        [fetchRequest setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"matchinnings"]];
        [fetchRequest setIncludesSubentities:YES];
        [fetchRequest setResultType:NSManagedObjectResultType];
        //[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:@"matchinnings.number", nil]];
        //[fetchRequest valueForKeyPath:@"matchinnings.number"];
        //[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:@"matchinnings", @"number", nil]];
        //[fetchRequest setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"matchinnings.number"]];
        //[fetchRequest setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects:@"matchinnings", @"matchinnings.number", nil]];

        // Edit the sort key as appropriate.
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

        [fetchRequest setSortDescriptors:sortDescriptors];

        // Edit the section name key path and cache name if appropriate.
        // nil for section name key path means "no sections".
        NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
        aFetchedResultsController.delegate = self;
        self.fetchedResultsController = aFetchedResultsController;

        [aFetchedResultsController release];
        [fetchRequest release];
        [sortDescriptor release];
        [sortDescriptors release];
    }

    return fetchedResultsController;
} 

В моем классе MatchContextMO я получаю сообщение об ошибке EXC_BAD_ACCESS настрока:

inningsArray = [newSet allObjects];

... в этом методе:

-(NSArray *)determineInningsOrder {

    NSArray* array =  nil;

    NSSet *newSet = [self.match valueForKey:@"matchinnings"];
    NSLog(@"Size of set %d", [newSet count]);

    NSArray *inningsArray = nil;

    @try {
        inningsArray = [newSet allObjects];
    }
    @catch (NSException *exception) {
        NSLog(@"Exception in matchinnings %@", [exception reason]);
    }

    Innings *inningA = [inningsArray objectAtIndex:0];
    Innings *inningB = [inningsArray objectAtIndex:1];

    if ([inningA isKindOfClass:Innings.class])
        NSLog(@"inningA is of type Innings");

    Innings* temp;

    NSNumber *numberA = [inningA valueForKey:@"number"];
    NSLog(@"numberA %d", [numberA intValue]);

    if ([numberA intValue] == 2) {
        temp = inningA;
        inningA = inningB;
        inningB = temp;
    }

    array = [NSArray arrayWithObjects:inningA, inningB, nil];

    return array;
} 

Я пытаюсь выяснить это за последнюю неделю.Это больше похоже на ошибки CoreData.

Ваша помощь очень ценится.

Я попытался перебрать возвращенный набор.По-прежнему получена ошибка «EXC_BAD_ACCESS» в строке [a addObject:inningsObject].NSLog размер набора говорит, хотя 2.

-(NSArray *)determineInningsOrder {

    NSArray* array =  nil;

    if (!self.match) {
        NSLog(@"Match is null");
        return nil;
    }


    NSMutableSet *newSet = [self.match valueForKey:@"matchinnings"];
    NSLog(@"Size of set %d", [newSet count]);

    //NSSet *inningsSet = [self.match matchinnings];
    NSArray *inningsArray = nil;

    NSEnumerator *fastEnumerator = [newSet objectEnumerator];

    id inningsObject;
    NSMutableArray *a = [[NSMutableArray alloc] initWithCapacity:[newSet count]];

    while ((inningsObject = [fastEnumerator nextObject])) {
        [a addObject:inningsObject];
    }

    Innings *inningA = [a objectAtIndex:0];
    Innings *inningB = [a objectAtIndex:1];

    [a release];
    if ([inningA isKindOfClass:Innings.class])
        NSLog(@"inningA is of type Innings");

    NSNumber *numberA = [inningA valueForKey:@"number"];
    NSLog(@"numberA %d", [numberA intValue]);

    if ([numberA intValue] == 2) {
        temp = inningA;
        inningA = inningB;
        inningB = temp;
    }

    array = [NSArray arrayWithObjects:inningA, inningB, nil];

    return array;
}

Ответы [ 7 ]

1 голос
/ 04 июля 2011

Конечно, если вы моделируете что-то в CoreData как Integer и предоставляете собственный класс для его реализации. Атрибут является объектом: NSNumber.

Пример:

.h:

// attributes
@property (nonatomic, retain) NSNumber *version;

// derived attributes
@property (nonatomic, readonly) NSInteger versionIntegerValue;
@property (nonatomic, readonly) NSString *versionStringValue;

.m:

@dynamic version;

- (NSInteger)versionIntegerValue {
  return [self.version integerValue];
}

- (NSString *)versionStringValue {
  return [NSString stringWithFormat:@"v%d", [self.version integerValue]];
}
0 голосов
/ 02 марта 2016

У меня та же проблема, EXC_BAD_ACCESS, когда я получаю доступ к соотношению один-ко-многим count, когда содержащиеся объекты находятся в состоянии ошибки.

myObject.oneToManyRelationshipProperty.count; <- EXC_BAD_ACCESS

Кажется, этоисправлено установкой relationshipKeyPathsForPrefetching во время запроса на выборку, которая будет «предварительно загружать» объекты отношений во время начальной выборки и не ошибка.

NSFetchRequest *fetchRequest = ...

fetchRequest.relationshipKeyPathsForPrefetching = @[@"yourProperty"];

Обратная связь по этому решению приветствуется.Я не понимаю, почему я получаю плохой доступ;Разве доступ к Fault не должен просто загружать объект (а не падать)?

0 голосов
/ 12 июня 2013

Это плохая идея давать имена свойств, такие как «число», «текст» или «описание», если вы не намеренно создаете подклассы. Базовые данные на самом деле выдают предупреждение, когда вы пытаетесь сделать последнее, но не со всеми зарезервированными словами. Из справочника классов NSPropertyDescription :

Обратите внимание, что имя свойства не может совпадать с именем метода без параметров в NSObject или NSManagedObject. Например, вы не можете дать свойству имя «описание». Существуют сотни методов в NSObject, которые могут конфликтовать с именами свойств, и этот список может расти без предупреждения от каркасов или других библиотек. Вам следует избегать очень общих слов (таких как «шрифт» и «цвет») и слов или фраз, которые пересекаются с парадигмами какао (таких как «isEditing» и «objectSpecifier»).

Используя valueForKey: последовательно, большую часть времени обходит эту проблему, но как только вы делаете вызов, такой как [inningA number], вы получаете ошибку.

0 голосов
/ 09 августа 2011

Немного сложно сказать без какой-либо дополнительной реализации, но я бы взглянул на:

  • Объект managedObjectContext, у управляемых объектов время жизни там с их собственным контекстом
  • Потоки: убедитесь, что вы обращаетесь к объектам и используете их собственный управляемый контекст в одном потоке
0 голосов
/ 06 июля 2011

Вы используете кеш.Это идет со всеми видами проблем.Я много раз читал документы и до сих пор не уверен, когда они обновятся.Попробуйте изменить кэш на ноль.Возможно, один из объектов в кэше больше не находится в хранилище и пытается получить к нему доступ.

Также избавьтесь от этих строк.На этом этапе они бесполезны, и, судя по всему, ваша программа не будет полезна:

    [fetchRequest setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"matchinnings"]];
    [fetchRequest setIncludesSubentities:YES];
    [fetchRequest setResultType:NSManagedObjectResultType];

Где создается управляемый текст объекта?Это в том же потоке, что вы запускаете этот код?У него все еще есть счет?Попробуйте NSLog(@"MOC Retain count: %i", [managedObjectContext retainCount]); Если это не в том же потоке, убедитесь, что это так.Это не потокобезопасно, и вы получите эти ошибки, если это не так.

Как вы устанавливаете соответствие?Это не ясно из вашего кода.NSFetchedResultsController полезен для заполнения табличного представления, но сопоставление является свойством.Как это установлено?NSFetchedResultsController правильный интерфейс для использования?Будет ли работать нормальная загрузка?

Если ничего из этого не сработает, я думаю, что лучше, чтобы вы разместили здесь содержимое всего файла.Как уже говорили другие, что там правильно, и очень трудно диагностировать то, чего мы не видим.

0 голосов
/ 05 июля 2011

Если matchinnings ключ - это имя для отношения ко многим, тогда:

[self.match valueForKey:@"matchinnings"];

... вернет не NSSet, а NSMutableSet. Когда вы присваиваете его NSSet примерно так:

NSSet *newSet = [self.match valueForKey:@"matchinnings"];

это может привести к проблемам, если вы забудете и попытаетесь что-то изменить.

Однако в данном случае это, вероятно, не проблема. Скорее всего, вы вообще не получаете набор. Я бы подтвердил, что вы получаете NSMutableSet возвращается.

Я могу сказать, что вы абсолютно уверены, что эта проблема не вызвана неисправностями. Во-первых, вы явно не извлекаете ошибки, а во-вторых, ошибка не может вызвать проблемы такого рода. Всякий раз, когда к атрибуту объекта, представляющего ошибку, осуществляется доступ, полный объект читается (ошибочно в жаргоне.) Ошибки никогда не вызывают проблем, связанных с доступом к атрибуту.

0 голосов
/ 04 июля 2011

Какой тип объекта inningA или inningB?Убедитесь, что:

  • В классе определено свойство 'number'
  • В объектной модели определено свойство 'number'

Если это всеправильно, пожалуйста, переформатируйте ваш вопрос, чтобы мы могли его легче прочитать.

Также вам будет понятнее, куда вы вызываете нижнюю функцию?И предоставить остальную часть MatchContectMO.Я не уверен, что это такое?Это определение МО?Или есть что-то, что содержит МО?(Имя не совсем понятно).

...