【问题标题】:Core Data with Array Attribute具有数组属性的核心数据
【发布时间】:2013-10-19 09:46:30
【问题描述】:

以下是实体Player的头文件。

@interface Player : NSManagedObject

@property (nonatomic, retain) NSNumber * experience;
@property (nonatomic, retain) id items;
@property (nonatomic, retain) NSNumber * level;

@end

@interface items : NSValueTransformer
@end

items 本质上是带有NSNumber 元素的NSMutableArray。在一个函数中,我正在更新这个数组:

- (void)itemWasDropped:(ItemIndex)item
{ // _player has been correctly retrieved from the database
    // the current number of this item
    int nNum = [[_player.items objectAtIndex:item] intValue];
    // to increment the number
    [_player.items replaceObjectAtIndex:item withObject:[NSNumber numberWithInt:nNum + 1]];
}

这个函数被完美地调用了。我将上下文保存在 viewWillDisappear 函数中。

- (void)viewWillDisappear:(BOOL)animated
{ // _moc is an NSManagedObjectContext instance that has been correctly initialised.
    // to update the database
    NSError* err = nil;
    BOOL bSucc = [_moc save:&err];
    if (err || !bSucc)
    {
        ...
    }
}

问题是只要我不在任务栏中关闭应用程序,更新在其他视图中可见。有什么问题?有人可以帮忙吗?

【问题讨论】:

  • 每个视图都使用自己的托管对象上下文吗?
  • 不,上下文是一样的。每个视图都向 AppDelegate 询问上下文。如果上下文尚未初始化,则将其初始化并返回。如果有,AppDelegate 简单地返回它。
  • 刚刚解决了。为了更新核心数据实体中的数组属性,必须将该数组分配给视图控制器类中的另一个@property 数组或其他任何东西,并更新@property 数组。在数据库更新之前,@property 数组必须被分配回实体属性。

标签: ios objective-c core-data


【解决方案1】:

核心数据可以存储数组,但您必须使用“可转换”属性。一般来说,它不是很好的设计。一种简单的解决方案是将您的数字数组转换为可以存储的东西。例如,在许多情况下,只使用一个字符串就足够了。

编码:

player.items = [numbers componentsJoinedByString:@","];
// Swift
player.items = numbers.joinWithSeparator(",")

解码:

NSMutableArray* numbers = [NSMutableArray array];
for (NSString *s in [player.items componentsSeparatedByString:@","]) {
  [numbers addObject:@([s integerValue])];
}
// Swift
let numbers = player.items.characters.split { $0 == "," } .map { Int($0!) }

【讨论】:

  • 谢谢,但 Core Data 可以通过 Transformable 做到这一点。我已经尝试过了,它有效。
  • 刚刚解决了。为了更新核心数据实体中的数组属性,必须将该数组分配给视图控制器类中的另一个@property 数组或其他任何东西,并更新@property 数组。在数据库更新之前,@property 数组必须被分配回实体属性。
  • 如果你已经解决了,你应该详细发布你的答案,以便其他人可以阅读和理解你的解决方案。另外,您为什么不使用与不同实体类型的一对多关系?
  • 网站说我在几十小时内无法回答我自己的问题。因为数组有预定义的长度并且只存储预定义的值,所以我没有费心去补关系。
【解决方案2】:

刚刚解决了。为了更新核心数据实体中的数组属性,必须将该数组分配给视图控制器类中的另一个@property 数组,或者更新@property 数组。在数据库更新之前,@property 数组必须被分配回实体属性。

// to hold the player items
// _player.items cannot be directly updated
@property (strong, nonatomic) NSMutableArray* items;

- (void)viewDidLoad
{
    [super viewDidLoad];
    ...
    NSError* err = nil;
    NSMutableArray* results = [[_moc executeFetchRequest:fr error:&err] mutableCopy];
    if (err || results.count == 0)
    {
        ...
    } else
    {
        _player = [results objectAtIndex:0];
        _items = _player.items;
    }
}

// events
- (void)itemWasDropped:(ItemIndex)item
{
    // the current number of this item
    int nNum = [[_items objectAtIndex:item] intValue];
    // to increment the number
    [_items replaceObjectAtIndex:item withObject:[NSNumber numberWithInt:nNum + 1]];
}

- (void)viewWillDisappear:(BOOL)animated
{
    // to update the database
    _player.items = _items;
    NSError* err = nil;
    BOOL bSucc = [_moc save:&err];
    if (err || !bSucc)
    {
         ...
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多