将资源注入 NSManagedObject 子类实例
Posted
技术标签:
【中文标题】将资源注入 NSManagedObject 子类实例【英文标题】:Injecting resources into NSManagedObject subclass instances 【发布时间】:2011-11-26 13:34:07 【问题描述】:我正在研究如何将资源注入到 NSManagedObject 子类实例中,但找不到合理的方法。
简单地说,我有一个对象,它代表实体的行为方法所需的服务。此服务需要在运行时可用。
在 Plain-Old-Objective-C-Object 中,我只需将此对象作为构造函数参数传递,或者在构造后通过属性设置它。类似于有多少对象需要和使用委托。
但是,awakeFromInsert 和 awakeFromFetch 显然不带参数,我也找不到任何地方可以挂接到 NSManagedObjectContext 以配置 NSManagedObjects 初始化后。
有人对此有解决方案吗?
作为一个完全人为的例子:
@interface ProductEntity : NSManagedObject
@property (nonatomic, retain) NSNumber *unitPrice;
@property (nonatomic, retain) MyTaxCalculatorService *taxCalculatorService;
- (void)grossPriceForUnits:(NSUInteger)units;
@end
@implementation ProductEntity
@dynamic unitPrice;
@synthesize taxCalculatorService
- (void)grossPriceForUnits:(NSUInteger)units
return [self.taxCalculatorService grossAmountForUnitPrice:self.unitPrice quantity:units];
@end
忽略这是否是计算总价格的最佳方法(这是一个人为的示例),我如何将 taxCalculatorService 实例放入 ProductEntity?我无法覆盖 init,也找不到可以始终调用 [entity setTaxCalculatorService:service] 的任何地方。
想法?
【问题讨论】:
您是在谈论“服务”类的单个共享实例还是每个对象都有自己的实例? 每个实体都有一个服务实例的引用。有些人可能会分享,有些人可能不会。在我设计的示例中,您可以想象某些产品的税收计算策略与其他产品不同。 【参考方案1】:awakeFromFetch / awakeFromInsert 将始终被调用。您将不得不从另一个方向接近它 - 托管对象将不得不从其他一些类请求“服务”实例(我认为这将是一个类方法) - 在您的 awakeFrom* 方法中是这样的:
self.serviceProvider = [ServiceProvider getServiceProviderForObject:self];
然后您的ServiceProvider
类将拥有有关托管对象的所有信息并可以返回适当的实例。
【讨论】:
这与我正在使用的解决方法非常相似 - 一个单例助手,它保留 NSManagedObjectContext->NSManagedObject 子类类型名称->键+值对的属性的三级字典以在实例上设置。然后,正如您所说, NSManagedObject 子类 awakeFrom(Insert|Fetch) 要求该单例进行最终初始化。虽然这一切都相当复杂 - 我希望有更简单的东西。【参考方案2】:看起来,你不能直接调用以下吗?
myProductEntityInstance.taxCalculatorService = [[MyTaxCalculatorService alloc] init];
它被定义为具有保留的属性,因此您的托管对象应该保留对它的引用。请注意,在您对实体所在的上下文调用 save 之前,您对托管对象所做的更改不会持久化
【讨论】:
问题是 在哪里 调用它。任何NSFetchRequest
或遵循实体中定义的任何关系都可以使实体存在。理论上,我可以跟踪应用程序中对executeFetchRequest
的每次调用,代码会遍历每个返回实体的图形以查找任何 ProductEntities 并在它们上设置该属性。太可怕了。
哦...而且,为了好玩,其中一些 executeFetchRequests
将隐藏在像 NSFetchedResultsController
这样的框架代码中,因此在这些情况下甚至无法设置属性.【参考方案3】:
在我看来,到目前为止,最简洁的方法是将 GrossAmountForUnitPrice:quantity: 转换为 TaxCalculatorService 类的 Class 方法。
然后您可以调用[TaxCalculatorService grossAmountForUnitPrice:self.unitPrice quantity:units]
而无需实例化 taxCalculatorService 类的实例。
这假定您的 TaxCalculatorService 未使用影响其返回值的状态(例如特定区域设置的税率或类似的税率)进行实例化。如果是这样,您当然需要在此处使用该信息来实例化您所描述的实例,因此如果需要该附加信息,您可以将其作为类方法的附加参数传入。
【讨论】:
以上是关于将资源注入 NSManagedObject 子类实例的主要内容,如果未能解决你的问题,请参考以下文章
NSManagedObject 有没有办法将创建的子类导入 xcdatamodel 文件