在 NSManagedObject class 中初始化 @NSManaged 变量?

Initialize @NSManaged variables in an NSManagedObject class?

我正在将用 Swift 编写的项目转换为使用 CoreData。一切正常,除了现在我正在尝试将自定义 class 转换为 NSManagedObject class 以将其属性存储在 CoreData 中。它看起来像这样:

import UIKit
import CoreData

class Jar: NSManagedObject {

    @NSManaged var name: String
    @NSManaged var jarDescription: String
    @NSManaged var jarType: UIImage
    @NSManaged var progress: Int
    @NSManaged var jarSize: Int

    /*
    init() {

        name = "Some Jar"
        jarType = UIImage(named: "EmptyJar3.png")
        progress = 0
        jarSize = 60
        jarDescription = ""

   */

}

我已经注释掉了 init(),因为根据我的阅读,您不能在 NSManagedObject 上使用初始化方法。但是,我在项目的其他地方有代码实例化类型为 Jar 的对象,对于未明确为此 class 设置的属性,我想为这些属性设置某种默认初始值.

有没有办法在 class Jar: NSManagedObject 中执行此操作?如果我正在编写检查方法以查看是否设置了属性,然后将它们显式保存到 CoreData,这似乎会变得非常混乱,我在任何地方实例化了一个新的 Jar 对象。

您可以覆盖 NSManagedObject 的 awakeFromInsert 方法来填充默认值。请参阅 Apple 文档 here

如果您从 Objective-C 移植应用程序,那么为什么不直接执行您的 ObjC 代码所做的事情(显然,它没有实现 -init)。

可以提供您自己的自定义初始化方法,但您必须确保initWithEntity:insertIntoManagedObjectContext:被正确调用并且您最好仔细阅读文档。

可以覆盖awakeFromInsertand/orawakeFromFetch,但您应该了解这样做涉及的一些特殊情况。

我发现,一般来说,如果您希望进行特殊初始化,那么您最好编写工厂方法。我相信你可以对 swift 中的 "class methods" 做同样的事情,但我还没有理由写任何 swift,所以我不知道 swift ], 所以我会用 ObjC 给出例子,你可以解释剩下的。

例如...

+ (NSString*)entityName
{
    return @"Jar";
}

+ (instancetype)jarWithName:(NSString*)name
                  imageName:(NSString*)imageName
                       size:(NSUInteger)size
     inManagedObjectContext:(NSManagedObjectContext*)context
{
    Jar *jar = [NSEntityDescription
        insertNewObjectForEntityForName:[self entityName]
                 inManagedObjectContext:context];
    jar.name = name;
    jar.jarDescription = @"";
    jar.jarType = [UIImage imageNamed:imageName];
    jar.progress = 0;
    jar.jarSize = size;
    return jar;
}

+ (instancetype)jarInManagedObjectContext:(NSManagedObjectContext*)context
{
    return [self jarWithName:@"Some Jar"
                   imageName:@"EmptyJar3.png"
                        size:60
      inManagedObjectContext:context];
}