简体   繁体   English

我可以对核心数据模型对象使用自定义初始化程序吗?

[英]Can I use a custom initializer for a core data model object?

I use Core Data and have an object ExerciseForRoutine . 我使用核心数据并有一个对象ExerciseForRoutine I'm currently manually creating it and then settings it's attributes, which seems to waste code. 我目前正在手动创建它,然后设置它的属性,这似乎在浪费代码。 Is there any way I can create a custom init method to handle this in one line (I know how to do around alloc/init, but core data has a different init method..) 有什么方法可以创建一个自定义的init方法来处理这一行(我知道如何围绕alloc / init进行操作,但是核心数据具有不同的init方法。)

Current Code: 当前代码:

ExerciseForRoutine *exerciseForRoutine = (ExerciseForRoutine *)[NSEntityDescription insertNewObjectForEntityForName:@"ExerciseForRoutine" inManagedObjectContext:managedObjectContext];
exerciseForRoutine.name = self.selectedExercise;
exerciseForRoutine.timeStamp = date;
exerciseForRoutine.muscleGroup = self.muscleName;
exerciseForRoutine.musclePicture = self.muscleURL;

ExerciseForRoutine Class ExerciseForRoutine类别

@class Routine;

@interface ExerciseForRoutine : NSManagedObject {
@private
}
@property (nonatomic, strong) NSDate * timeStamp;
@property (nonatomic, strong) NSString * name;
@property (nonatomic, strong) NSString * muscleGroup;
@property (nonatomic, strong) NSString * musclePicture;
@property (nonatomic, strong) Routine * exerciseToRoutine;

@end

@implementation ExerciseForRoutine
@dynamic timeStamp;
@dynamic name;
@dynamic muscleGroup;
@dynamic musclePicture;
@dynamic exerciseToRoutine;

I did this using awakeFromInsert and awakeFromFetch. 我使用awakeFromInsert和aawakeFromFetch做到了这一点。

From Apple's documentation: 从Apple的文档中:

In a typical Cocoa class, you usually override the designated initializer (often the init method). 在典型的Cocoa类中,通常会覆盖指定的初始化程序(通常是init方法)。 In a subclass of NSManagedObject, there are three different ways you can customize initialization —by overriding initWithEntity:insertIntoManagedObjectContext:, awakeFromInsert, or awakeFromFetch. 在NSManagedObject的子类中,可以通过三种不同的方式来自定义初始化—通过覆盖initWithEntity:insertIntoManagedObjectContext :、 awakeFromInsert或awakeFromFetch。 You should not override init. 您不应覆盖init。 You are discouraged from overriding initWithEntity:insertIntoManagedObjectContext: as state changes made in this method may not be properly integrated with undo and redo. 不鼓励您重写initWithEntity:insertIntoManagedObjectContext:因为在此方法中进行的状态更改可能未与undo和redo正确集成。

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/Articles/cdManagedObjects.html https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/Articles/cdManagedObjects.html

The classes which Xcode creates for handling core data objects should not be overridden, instead what you could do is create your own custom class which inherits from NSObject and write your methods to handle the managed object their. Xcode为处理核心数据对象而创建的类不应被覆盖,相反,您可以做的是创建自己的自定义类,该类从NSObject继承并编写方法以管理其托管对象。

Sol: You can do this with the help of the parameterized init method Sol:您可以借助参数化的init方法来执行此操作

Then it would look something like this 然后看起来像这样

CoreDataHelperClass *someobj = [[CoreDataHelperClass alloc]initWithname:@"name" andTimeStamp:@"Time" andMuscleGroup:@"musclegroup" andPicture:UIImagePNGRepresentation(someimageObj)];

To do the above you need to add your own init method in the CoreDataHelperClass class like this 为此,您需要像这样在CoreDataHelperClass类中添加自己的init方法

.h part of CoreDataHelperClass .h部分的CoreDataHelperClass

- (id)initWithName:(NSString*)name andTimeStamp:(NSString*)timeStamp andMuscleGroup:(NSString*)group andPicture:(NSData*)imageData;

.m part of CoreDataHelperClass .m是CoreDataHelperClass的一部分

- (id)initWithName:(NSString*)name andTimeStamp:(NSString*)timeStamp andMuscleGroup:(NSString*)group andPicture:(NSData*)imageData
{

//you assignment code to the core data attributes goes here

ExerciseForRoutine *obj = [[ExerciseForRoutine alloc]init];

obj.name = name;
obj.timestamp = timeStamp;

//and so on

return self;

}

Anyways what you could also do is pass a dictionary with the keyvalue pair get the values in your custom class or you may also pass an NSMutableArray like what ever suits your business model both will work. 无论如何,您还可以通过传递带有键值对的字典来获取自定义类中的值,或者您也可以传递NSMutableArray,就像适合您的业务模型的东西都可以使用一样。

You can get the values of Dictionary or Array inside your CoreDataHelperClass and assign those values to your attribute. 您可以在CoreDataHelperClass中获取Dictionary或Array的值,并将这些值分配给属性。

Hope i have got your query right if not then kindly mention the error part via comments 希望我的查询正确无误,然后请通过评论提及错误部分

To add to @Radix's answer, you should consider using mogenerator because it'll do much of that subclassing business for you. 要增加mogenerator的答案,您应该考虑使用mogenerator因为它将为您完成大部分子类业务。

http://rentzsch.github.io/mogenerator/ http://rentzsch.github.io/mogenerator/

See here for a guide to set it up and have it running on XCode 5. 有关在XCode 5上进行设置和运行的指南,请参见此处

There's a small caveat to watch out for though: if you get an assertion failure that reads: 有一个小警告需要注意:如果您得到一个断言失败,内容如下:

-[MOGeneratorApp setModel:] blah blah blah

Then you should point mogenerator to the .xcdatamodel file inside of the .xcdatamodeld package in your Run Script Phase, like so: 然后,你应该指向mogenerator.xcdatamodel文件内.xcdatamodeld包在你的运行脚本阶段,就像这样:

mogenerator -m Model.xcdatamodeld/Model.xcdatamodel -O Project/Model --template-var arc=true

Where Project is the name of your project and Model is the name of your model. 其中ProjectProject的名称,而ModelModel的名称。

See https://github.com/rentzsch/mogenerator/issues/169 . 参见https://github.com/rentzsch/mogenerator/issues/169

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM