DBAccess - 将自定义 class 对象设置为 DBObject 属性
DBAccess - Setting a custom class object as DBObject property
我是 iOS 开发和 DBAccess 框架的初学者,我遇到了一个可能很容易解决的问题,但我真的不知道如何表达它。
我的 DBObject class 扩展名:
页眉
//FavouriteProduct.h
#import <UIKit/UIKit.h>
#import <DBAccess/DBAccess.h>
#import "Product.h"
@interface FavouriteProduct : DBObject
@property Product *product;
@property NSString *userID;
@property NSString *productID;
@end
实施
//FavouriteProduct.m
#import "FavouriteProduct.h"
#import "Product.h"
@implementation FavouriteProduct
@dynamic productID;
@dynamic userID;
@dynamic product;
@end
Product.m 文件:
@implementation Product{
NSString *id;
float price;
float discount;
NSDictionary *ownerProduct;
NSDictionary *originalDict;
}
//I create my Product objects from JSON
-(instancetype)initWithJSONDictionary:(NSDictionary *)JSONDict{
self = [super init];
if (self) {
[self setValuesForKeysWithDictionary:JSONDict];
}
originalDict = [[NSDictionary alloc] initWithDictionary:JSONDict];
return self;
}
// + some more getter methods
Product.h 文件包含 getter 方法和上述 initWithJSONDictionary 方法的接口声明。
我尝试使用以下代码设置产品 属性:
FavouriteProduct *fav = [FavouriteProduct new];
fav.product = self.product; //self.product is an object of Product class
fav.productID = self.product.getProductID;
[fav commit];
我收到这个错误:
由于未捕获的异常 'NSInvalidArgumentException',正在终止应用程序,原因:'-[FavouriteProduct setProduct:]:无法识别的选择器发送到实例 0x16e5bf10'
我也这样试过:
FavouriteProduct *fav = [FavouriteProduct new];
fav.product = [[Product alloc]initWithJSONDictionary:self.product.getOriginalDictionary]; //set a Product object from NSDictionary
fav.productID = self.product.getProductID;
[fav commit];
我得到同样的错误。
我错过了什么?谢谢你的时间。
因为您的 FavouriteProduct 中的属性(我猜)是作为 @dynamic 实现的,所以没有由 objc 自动生成的 get/set 方法。因此,当分配发生时,会在尝试调用 setProduct:
时抛出异常
通常 DBAccess 会为您创建这些,但它只能为已知类型创建这些。
DBAccess 检查 class 并为它认为定义为 @dynamic 的任何属性分配存储类型,该列表在其支持方面是全面的,但它不能坚持自定义 classes 它不知道如何 store/reconstruct 他们。
现在,我本来希望它做的是创建一个 BLOB 列并尝试存储它,然后引发一个异常,说 class [=32= 不支持 NSKeyedArchiver ].我会调查为什么这没有发生。
如何让它工作?
好吧,您可以使产品 class 成为 DBObject,这将使 DBAccess 知道如何处理它以及如何存储它。或者您可以将 .product 属性 保留为 @sythensized,这意味着 DBAccess 不会尝试存储它。然后添加一个额外的 属性,例如 .productDictionary 并存储用于创建它的 NSDictionary,并且每次获得产品 属性 时,重建完整的对象并将其缓存在某处。
作为参考,这些是 DBAccess 无需额外扩展即可保留的对象类型。
NSNumber, NSString, NSImage/UIImage, NSArray, NSDictionary, NSDate, int, bool, long, float, char, short, long long, uchar, ushort, ulong, ulong long, double, char*, NSURL、NSData、NSMutableData、NSMutableArray、NSMutableDictionary、DBObject derived classes、NSObject(其中 class 实现了 NSKeyedArchiver)、int64、uint64。
如果您在 NSArray 或 NSDictionary 属性中存储内容,这些内容只能包含简单数据类型,不能包含自定义类型。因此,NSNumbers、日期、图像、字典和其他基本类型的数组都可以。但是包含您自己的自定义类型的数组和字典将无法持久化。
希望对您有所帮助,
阿德里安
我是 iOS 开发和 DBAccess 框架的初学者,我遇到了一个可能很容易解决的问题,但我真的不知道如何表达它。
我的 DBObject class 扩展名:
页眉
//FavouriteProduct.h
#import <UIKit/UIKit.h>
#import <DBAccess/DBAccess.h>
#import "Product.h"
@interface FavouriteProduct : DBObject
@property Product *product;
@property NSString *userID;
@property NSString *productID;
@end
实施
//FavouriteProduct.m
#import "FavouriteProduct.h"
#import "Product.h"
@implementation FavouriteProduct
@dynamic productID;
@dynamic userID;
@dynamic product;
@end
Product.m 文件:
@implementation Product{
NSString *id;
float price;
float discount;
NSDictionary *ownerProduct;
NSDictionary *originalDict;
}
//I create my Product objects from JSON
-(instancetype)initWithJSONDictionary:(NSDictionary *)JSONDict{
self = [super init];
if (self) {
[self setValuesForKeysWithDictionary:JSONDict];
}
originalDict = [[NSDictionary alloc] initWithDictionary:JSONDict];
return self;
}
// + some more getter methods
Product.h 文件包含 getter 方法和上述 initWithJSONDictionary 方法的接口声明。
我尝试使用以下代码设置产品 属性:
FavouriteProduct *fav = [FavouriteProduct new];
fav.product = self.product; //self.product is an object of Product class
fav.productID = self.product.getProductID;
[fav commit];
我收到这个错误: 由于未捕获的异常 'NSInvalidArgumentException',正在终止应用程序,原因:'-[FavouriteProduct setProduct:]:无法识别的选择器发送到实例 0x16e5bf10'
我也这样试过:
FavouriteProduct *fav = [FavouriteProduct new];
fav.product = [[Product alloc]initWithJSONDictionary:self.product.getOriginalDictionary]; //set a Product object from NSDictionary
fav.productID = self.product.getProductID;
[fav commit];
我得到同样的错误。
我错过了什么?谢谢你的时间。
因为您的 FavouriteProduct 中的属性(我猜)是作为 @dynamic 实现的,所以没有由 objc 自动生成的 get/set 方法。因此,当分配发生时,会在尝试调用 setProduct:
时抛出异常通常 DBAccess 会为您创建这些,但它只能为已知类型创建这些。
DBAccess 检查 class 并为它认为定义为 @dynamic 的任何属性分配存储类型,该列表在其支持方面是全面的,但它不能坚持自定义 classes 它不知道如何 store/reconstruct 他们。
现在,我本来希望它做的是创建一个 BLOB 列并尝试存储它,然后引发一个异常,说 class [=32= 不支持 NSKeyedArchiver ].我会调查为什么这没有发生。
如何让它工作?
好吧,您可以使产品 class 成为 DBObject,这将使 DBAccess 知道如何处理它以及如何存储它。或者您可以将 .product 属性 保留为 @sythensized,这意味着 DBAccess 不会尝试存储它。然后添加一个额外的 属性,例如 .productDictionary 并存储用于创建它的 NSDictionary,并且每次获得产品 属性 时,重建完整的对象并将其缓存在某处。
作为参考,这些是 DBAccess 无需额外扩展即可保留的对象类型。
NSNumber, NSString, NSImage/UIImage, NSArray, NSDictionary, NSDate, int, bool, long, float, char, short, long long, uchar, ushort, ulong, ulong long, double, char*, NSURL、NSData、NSMutableData、NSMutableArray、NSMutableDictionary、DBObject derived classes、NSObject(其中 class 实现了 NSKeyedArchiver)、int64、uint64。
如果您在 NSArray 或 NSDictionary 属性中存储内容,这些内容只能包含简单数据类型,不能包含自定义类型。因此,NSNumbers、日期、图像、字典和其他基本类型的数组都可以。但是包含您自己的自定义类型的数组和字典将无法持久化。
希望对您有所帮助,
阿德里安