Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 从核心数据获取数组_Objective C_Ios_Core Data - Fatal编程技术网

Objective c 从核心数据获取数组

Objective c 从核心数据获取数组,objective-c,ios,core-data,Objective C,Ios,Core Data,我已经用几个字符串字段和几个数组字段建立了一个模型。模型将保存为: - (void)saveLevel:(NSString*)level traps:(NSArray*)traps whirls:(NSArray*)whirls accels:(NSArray*)accels walls:(NSArray*)walls dest:(NSString*)dest jupiter:(NSString*)jupiter rating:(NSNumber*)pRating; { if (m

我已经用几个字符串字段和几个数组字段建立了一个模型。模型将保存为:

- (void)saveLevel:(NSString*)level traps:(NSArray*)traps whirls:(NSArray*)whirls accels:(NSArray*)accels walls:(NSArray*)walls dest:(NSString*)dest jupiter:(NSString*)jupiter rating:(NSNumber*)pRating;
{   
    if (m_pMOC == nil) 
       // Retrieves the managed object context

    NSManagedObject* pNewLevel = [NSEntityDescription insertNewObjectForEntityForName:@"Level" inManagedObjectContext:m_pMOC];

    NSDate* pDate = [NSDate date];

    // Must have these four attributes
    [pNewLevel setValue:level forKey:@"Level_ID"];
    [pNewLevel setValue:jupiter forKey:@"Ball"];
    [pNewLevel setValue:pDate forKey:@"Creation_Date"];
    [pNewLevel setValue:dest forKey:@"Destination"];
    [pNewLevel setValue:pRating forKey:@"Rating"];

    // Optional attributes
    if ([traps count] != 0) 
        [pNewLevel setValue:traps forKey:@"Traps"];
    if ([whirls count] != 0) 
        [pNewLevel setValue:whirls forKey:@"Whirls"];
    if ([accels count] != 0) 
        [pNewLevel setValue:accels forKey:@"Accelerators"];
    if ([walls count] != 0) 
        [pNewLevel setValue:walls forKey:@"Walls"];

    NSError* pError;
    if (![m_pMOC save: &pError]) 
    // etc...
}
- (void)saveLevel:(NSString*)level traps:(NSArray*)traps whirls:(NSArray*)whirls accels:(NSArray*)accels walls:(NSArray*)walls dest:(NSString*)dest jupiter:(NSString*)jupiter rating:(NSNumber*)pRating;
{   
    if (m_pMOC == nil) 
    { // Code to get the managed object context from the delegate
    }
    NSManagedObject* pNewLevel = [NSEntityDescription insertNewObjectForEntityForName:@"Level" inManagedObjectContext:m_pMOC];
    NSManagedObject* pNewBall = [NSEntityDescription insertNewObjectForEntityForName:@"Ball" inManagedObjectContext:m_pMOC];
    [pNewBall setValue:jupiter forKey:@"a_Bounds"];
    NSManagedObject* pNewDest = [NSEntityDescription insertNewObjectForEntityForName:@"Dest" inManagedObjectContext:m_pMOC];
    [pNewDest setValue:dest forKey:@"a_Bounds"];

    NSDate* pDate = [NSDate date];

    // Must have these four attributes
    [pNewLevel setValue:level forKey:@"a_Level_ID"];
    [pNewLevel setValue:pDate forKey:@"a_Creation_Date"];
    [pNewLevel setValue:pRating forKey:@"a_Rating"];
    [pNewLevel setValue:@"Bob Dole" forKey:@"a_CreatedBy"];

    [pNewLevel setValue:pNewBall forKey:@"r_Ball"];
    [pNewLevel setValue:pNewDest forKey:@"r_Dest"];

    // Optional attributes
    if ([traps count] != 0) 
        [[pNewLevel mutableSetValueForKey: @"r_Trap"] addObjectsFromArray: traps];
    if ([whirls count] != 0) 
        [[pNewLevel mutableSetValueForKey: @"r_Whirl"] addObjectsFromArray: whirls];
    if ([accels count] != 0) 
        [[pNewLevel mutableSetValueForKey: @"r_Accel"] addObjectsFromArray: accels];
    if ([walls count] != 0) 
        [[pNewLevel mutableSetValueForKey: @"r_Wall"] addObjectsFromArray: walls];

    NSError* pError;
    if (![m_pMOC save: &pError]) 
    { // Error saving
    }
    else
    { // Successfully saved
    }
}
我有一个DataManager类,它处理从/到核心数据的获取/保存,在管理器内部,我验证了当我获取一个实体时,数组被获取,但是当它返回到调用它的类时,数组为零(另一方面,字符串刚好到达)。以下是提取代码和从提取中解析出返回值的代码:

- (NSArray*) getLevelWithID:(NSString*)level
{
    NSEntityDescription *pEntityDescription = [NSEntityDescription entityForName:@"Level" inManagedObjectContext:m_pMOC];
    NSFetchRequest *pRequest = [[[NSFetchRequest alloc] init] autorelease];
    [pRequest setEntity:pEntityDescription];
    NSPredicate* pPredicate = [NSPredicate predicateWithFormat:@"Level_ID == %@", level];
    [pRequest setPredicate: pPredicate];

    NSError* pError;
    NSArray* pLevels = [m_pMOC executeFetchRequest:pRequest error:&pError];
    if (pLevels == nil) 
    {
        NSLog(@"Could not find the level with Level_ID = %@",level);
        abort();
    }

    NSArray* pAccels = [pLevels valueForKey:@"Accelerators"];
    NSArray* pTraps = [pLevels valueForKey:@"Traps"];
    NSArray* pWalls = [pLevels valueForKey:@"Walls"];
    NSArray* pWhirls = [pLevels valueForKey:@"Whirls"];

    return pLevels;
}
我在最后四个数组上设置了一个断点,它们中有对象,但在检索它们的函数中(如下所示),它们是nil

- (void) initLevel:(NSArray*)pLevelObjects
{
    Level* pLevel = [pLevelObjects objectAtIndex:0];

    NSString* pJupiter = pLevel.Ball;
    NSString* pDest = pLevel.Destination;

    NSArray* pAccels = [pLevel valueForKey:@"Accelerators"];
    NSArray* pTraps = [pLevel valueForKey:@"Traps"];
    NSArray* pWalls = [pLevel valueForKey:@"Walls"];
    NSArray* pWhirls = [pLevel valueForKey:@"Whirls"];
    ... (other initialization of the level) ...
}
我对此感到困惑。字符串值存在,但数组不存在。我最初尝试使用点符号(NSArray*pAccels=pLevel.Accelerators等),但结果相同

想法

编辑:从视图控制器调用initLevel:

- (void) startGameWithLevelID:(NSString*)pLevelID
{
    NSLog(@"MyViewController - beginGameWithLevelID");
    NSArray* pLevel = [[DataManager getDataManager] getLevelWithID:pLevelID];
    if (pLevel == nil || [pLevel count] == 0) 
    {
        NSLog(@"Didn't retrieve any level with id %@", pLevelID);
        abort();
    }
    else
    {
        CGRect newFrame = makeScreen([UIScreen mainScreen].applicationFrame);
        GameBoard* pGB = [[GameBoard alloc] initWithFrame: newFrame];
        pGB.m_pMyVC = self;
        [pGB initLevel: pLevel];
        [self.view addSubview: (UIView*)pGB];

        [pGB release];
    }
}
编辑:我最近将数组重新分解成单独的实体,并与级别建立一对一的关系;该级别与这些实体具有多对多关系。我还更改了名称以更好地遵守约定:所有属性和关系现在都以小写字母开头。我分别用a_u和r_u作为属性和关系的前缀。保存“-[NSCFString\u iskindof entity:]:发送到实例0x4d83120的选择器无法识别时出错。这并没有太大的帮助,但我发现问题后会告诉你。目前,用于保存的代码如下所示:

- (void)saveLevel:(NSString*)level traps:(NSArray*)traps whirls:(NSArray*)whirls accels:(NSArray*)accels walls:(NSArray*)walls dest:(NSString*)dest jupiter:(NSString*)jupiter rating:(NSNumber*)pRating;
{   
    if (m_pMOC == nil) 
       // Retrieves the managed object context

    NSManagedObject* pNewLevel = [NSEntityDescription insertNewObjectForEntityForName:@"Level" inManagedObjectContext:m_pMOC];

    NSDate* pDate = [NSDate date];

    // Must have these four attributes
    [pNewLevel setValue:level forKey:@"Level_ID"];
    [pNewLevel setValue:jupiter forKey:@"Ball"];
    [pNewLevel setValue:pDate forKey:@"Creation_Date"];
    [pNewLevel setValue:dest forKey:@"Destination"];
    [pNewLevel setValue:pRating forKey:@"Rating"];

    // Optional attributes
    if ([traps count] != 0) 
        [pNewLevel setValue:traps forKey:@"Traps"];
    if ([whirls count] != 0) 
        [pNewLevel setValue:whirls forKey:@"Whirls"];
    if ([accels count] != 0) 
        [pNewLevel setValue:accels forKey:@"Accelerators"];
    if ([walls count] != 0) 
        [pNewLevel setValue:walls forKey:@"Walls"];

    NSError* pError;
    if (![m_pMOC save: &pError]) 
    // etc...
}
- (void)saveLevel:(NSString*)level traps:(NSArray*)traps whirls:(NSArray*)whirls accels:(NSArray*)accels walls:(NSArray*)walls dest:(NSString*)dest jupiter:(NSString*)jupiter rating:(NSNumber*)pRating;
{   
    if (m_pMOC == nil) 
    { // Code to get the managed object context from the delegate
    }
    NSManagedObject* pNewLevel = [NSEntityDescription insertNewObjectForEntityForName:@"Level" inManagedObjectContext:m_pMOC];
    NSManagedObject* pNewBall = [NSEntityDescription insertNewObjectForEntityForName:@"Ball" inManagedObjectContext:m_pMOC];
    [pNewBall setValue:jupiter forKey:@"a_Bounds"];
    NSManagedObject* pNewDest = [NSEntityDescription insertNewObjectForEntityForName:@"Dest" inManagedObjectContext:m_pMOC];
    [pNewDest setValue:dest forKey:@"a_Bounds"];

    NSDate* pDate = [NSDate date];

    // Must have these four attributes
    [pNewLevel setValue:level forKey:@"a_Level_ID"];
    [pNewLevel setValue:pDate forKey:@"a_Creation_Date"];
    [pNewLevel setValue:pRating forKey:@"a_Rating"];
    [pNewLevel setValue:@"Bob Dole" forKey:@"a_CreatedBy"];

    [pNewLevel setValue:pNewBall forKey:@"r_Ball"];
    [pNewLevel setValue:pNewDest forKey:@"r_Dest"];

    // Optional attributes
    if ([traps count] != 0) 
        [[pNewLevel mutableSetValueForKey: @"r_Trap"] addObjectsFromArray: traps];
    if ([whirls count] != 0) 
        [[pNewLevel mutableSetValueForKey: @"r_Whirl"] addObjectsFromArray: whirls];
    if ([accels count] != 0) 
        [[pNewLevel mutableSetValueForKey: @"r_Accel"] addObjectsFromArray: accels];
    if ([walls count] != 0) 
        [[pNewLevel mutableSetValueForKey: @"r_Wall"] addObjectsFromArray: walls];

    NSError* pError;
    if (![m_pMOC save: &pError]) 
    { // Error saving
    }
    else
    { // Successfully saved
    }
}
再次感谢您的帮助,抱歉这篇文章太长,但我希望这能帮助其他核心数据新手(如我)学到一些东西

最终编辑:好的,在重构之后,我终于找到了将数组保存为对象的解决方案(尽管我不确定这是否是最有效的方法)。下面是添加一堆“陷阱”的代码。传递到函数中的数组是陷阱的边界,它将被存储。然后与级别形成关系(注意,不必同时由陷阱和级别设置,只需其中一个,因为核心数据以另一种方式处理)

可能的阵列误用 在第一个代码段中,您正在
NSArray
上调用
valueForKey:
,结果是一个数组,因为该代码迭代
pLevels
,将
valueForKey:
参数传递给内部的每个对象并组合值

这就是为什么

在第二段代码中,首先从数组中获取一个pLevel,然后对实体而不是数组执行
valueForKey:
选择器。所以结果就是这个特定的物体里的东西

可能您的某些实体具有这些字段,因此所有这些字段的组合结果具有一些值,但某些特定的结果不具有这些值

可能的核心数据滥用 您说您在核心数据实体中保留了一个数组。你是怎么做到的?没有特殊类型来保存数组,因此通常必须将其存储为二进制数据,并使用
[NSKeyedArchiver archivedDataWithRootObject:array]
执行编码。可能是存储和获取不正确,因为您试图在非数组字段中存储数组


您是否也遇到过任何崩溃?

在视图控制器中,阵列仍有对象。。。可能需要保留。如果存在保留问题,您将在
级别*pLevel=[pLevelObjects objectAtIndex:0]
上崩溃。我将在下班(或有空闲时间)时研究第一种情况。至于第二种情况,我尝试将数据库中的对象声明为二进制数据(NSData),而不是“未定义”(和“瞬态”,这是我记得core data ref说要使用数组的方式),但这似乎并没有缓解问题。我正在考虑将数组重构成单独的实体,每个实体与级别之间都有“对一”的关系(级别与级别之间都有“对多”的关系)。唯一的问题是,文档中没有非常清楚地说明如何有效地批量保存这些新实体。我甚至想不出我会怎么做。你知道最好的方法吗?这一定是一个核心数据误用问题,因为使用点表示法(例如pLevel.Accelerators)会出现零数组,我会编辑帖子,包括save,看看我是否对
NSManagedObject
子类做了错误的事情,使用
valueForKey:
和点表示法是一样的,除非你超越了
valueForKey:
你自己。它将调用相同的方法并返回相同的结果。