CoreData - 无法将空字符串设置为属性的默认值

时间:2011-03-01 12:47:49

标签: xcode core-data migration string

我的datamodel中有一个实体,其字符串属性当前是可选的,我想将其转换为必需属性,其默认值为空字符串。

正如其他人发现的那样,在Xcode CoreData数据建模器中保留默认值为空会导致验证错误(因为设计者将此解释为NULL),但尝试使用'',“”或@“”作为默认值结果在那些文字字符被解释为默认字符,而不是空的零长度字符串,根据需要。

我确实在Google上找到this thread,但是,除了解决方案真的很难看(模型定义在.xcdatamodel和objc源之间拆分)之外,它也不适用于轻量级迁移,因为这些迁移已经完成仅基于.xcdatamodel文件,并且未加载实体实现中的objc逻辑。

有没有办法在数据模型设计师中实现这一目标?

8 个答案:

答案 0 :(得分:30)

这是一个非常有趣的问题。经过一些测试后,我认为这是不可能的,因为数据模型中的文本字段的配置方式。

原则上,您可以使用\u2205的unicode空集字符来表示默认的空字符串,但文本字段似乎不接受任何转义,因此它会将任何尝试转义为unicode字符代码转换为代码字符本身的文字字符串,例如输入'\ u2205'最终为文字'\ u2205'。

理论上,您可以编写一个实用程序app来读取图形生成的托管对象模型文件,然后以编程方式将属性default设置为等于空字符串,然后将文件保存回磁盘。我说“理论上”是因为没有记录的方法来保存代码中的托管对象模型文件。您可以读取一个并在内存中修改它,但不能保留更改。

我认为有点疏忽。

我认为您没有其他选择,只能在模型首次加载时以实际方式设置默认空字符串。这很简单,但它很丑,你必须记住你做过(特别是如果你迁移版本),但我认为现在这是唯一的选择。

答案 1 :(得分:15)

剔除您最喜爱的XML编辑器(我刚刚使用过Emacs)并深入查看contents包内.xcdatamodel包内的.xcdatamodeld文件。然后只需将defaultValueString="" XML属性添加到<attribute>...</attribute>括号内的<entity>...</entity>元素。 这是一个例子:

<attribute name="email" attributeType="String" defaultValueString="" syncable="YES"/>

我无法谈论这是否能够继续迁移,因为我还没有这样做。

答案 2 :(得分:7)

我通过覆盖我的字段的getter来解决这个问题 - 如果它包含null,我会返回一个空字符串:

-(NSString *)unit {
    if ([self primitiveValueForKey:@"unit"] == NULL) {
        return @"";
    } else {
        return [self primitiveValueForKey:@"unit"];
    }
}

到目前为止它似乎正在做这个伎俩,我认为它不会影响迁移(虽然我不太了解它们肯定会说)。毕竟,我真的不在乎数据库中是否有空字符串或空字符串 - 只要我在询问字段时得到“”而不是null。

答案 3 :(得分:6)

我解决此问题的方法是创建一个NSManagedObject子类,并在awakeFromInsert中处理空字符串替换NULL值。然后我将所有实体设置为此子类的子项而不是NSManagedObject的子项。这里的假设是我希望默认情况下将给定实体中的每个字符串属性设置为空字符串(它不起作用,或者至少需要额外的逻辑,如果你想要一些在同一实体内保持NULL。)

这可能是一种更有效的方法,但由于它只是在创建实体时才会被调用,所以我认为这不会对性能造成太大影响。

- (void)awakeFromInsert {
    [super awakeFromInsert];

    NSDictionary *allAttributes = [[self entity] attributesByName];
    NSAttributeDescription *oneAttribute;

    for (NSString *oneAttributeKey in allAttributes) { 
        oneAttribute = [allAttributes objectForKey:oneAttributeKey];
        if ([oneAttribute attributeType] == NSStringAttributeType) {
            if (![self valueForKey:[oneAttribute name]]) {
                [self setValue:@"" forKey:[oneAttribute name]];
            }
        }
    }
}

答案 4 :(得分:3)

您可以手动执行此操作。 在模型类中,覆盖awakeFromInsert并将字符串设置为空字符串

夫特:

$.ajax({
                url: xxxxxx,
                type: 'POST',
                data: "12345",
                dataType: 'text',
                success: function (successMsg) {
                    $('#Question3', container).html(successMsg);
                },
                error: function () {
                    debugger;
                }
            });

目标-C

override func awakeFromInsert()
{
    super.awakeFromInsert()
    self.stringProperty = ""
}

答案 5 :(得分:1)

这是基于David Ravetti的回答和edelaney05评论的Swift解决方案。另外,我添加了可选性检查。

此解决方案在我的项目中运行良好。

statsmodels

答案 6 :(得分:0)

基于Scott Marks answer的更简单的解决方案,可以避免语法错误:

首先,临时设置易于查找的默认值,例如here you are。使用任何文本编辑器打开contents包中.xcdatamodel包中的.xcdatamodeld文件。然后只需执行搜索即可,用此文件中的"here you are"替换字符串""

迁移没有问题。

答案 7 :(得分:-1)

也许我已经迟到了这个答案,但我是谷歌搜索并找到了这个论坛。

解决方案非常简单:

  1. 单击xcdatamodelId(在左侧屏幕上)
  2. 将实体视图更改为图表
  3. 双击您想要的任何属性,菜单将显示在右侧。
  4. 所有更改都很简单。

    第2部分

    For Part 2

    第3部分

    For Part 3