我正在努力寻找一种方法,使用Realm.io和Objective-c将多个属性组合成一个主键。
以此对象为例:
@interface Beacon : RLMObject
@property NSString *uuid;
@property int major;
@property int minor;
@end
RLM_ARRAY_TYPE(Beacon)
我如何组合,例如uuid,major和minor成为一个主键?
答案 0 :(得分:2)
我在当前项目中如何完成它是为复合键添加新属性,使其成为主键。然后,覆盖复合键的所有部分的setter,并调用更新复合键的函数。
我的ObjC很弱,所以我无法为您提供用该语言编写的可靠示例,但这里有一个可能有帮助的Swift示例。
var func = function(_this) {
return function() {
document.write('called!');
};
};
var onReady = func(this); // In your code, the declation of func and its exection are done together
// At this point onReady is equal to the inner function
// function() {
// document.write('called!');
// }
$(onReady);
答案 1 :(得分:2)
这是Objective-C解决方案。它利用了只能覆盖ignoredProperties
的事实。它比Swift版本更冗长,但它有效,所以如果你需要ObjC中的复合键,这可能是你最好的选择。一个可能的限制是公共属性的KVO不起作用,但是,因为Realm期望在将对象添加到Realm之后主键保持不变,所以这种限制可能很小。如果你确实想要KVO,你可以通过注册in this document from Apple所描述的从属密钥来解决它。
在CompositeKeyObject.h中:
@interface CompositeKeyObject : RLMObject
@property (nonatomic, strong) NSString* partOne;
@property (nonatomic, strong) NSString* partTwo;
@end
在CompositeKeyObject.m中:
@interface CompositeKeyObject ()
@property (nonatomic, strong) NSString* partOneValue;
@property (nonatomic, strong) NSString* partTwoValue;
@property (nonatomic, strong) NSString* compositeKey;
@end
@implementation CompositeKeyObject
- (instancetype)initWithValue:(id)value
{
// Need to make a copy and set the correct "value" properties.
// Otherwise, the object won't be created properly.
NSMutableDictionary* valueCopy = [value mutableCopy];
if(valueCopy[@"partOne"] != nil) {
valueCopy[@"partOneValue"] = valueCopy[@"partOne"];
}
if(valueCopy[@"partTwo"] != nil) {
valueCopy[@"partTwoValue"] = valueCopy[@"partTwo"];
}
self = [super initWithValue:[valueCopy copy]];
if(self != nil) {
// Make sure primary key is in sync.
[self updatePrimaryKey];
}
return self;
}
- (void)setPartOne:(NSString *)partOne
{
self.partOneValue = partOne;
[self updatePrimaryKey];
}
- (void)setPartTwo:(NSString *)partTwo
{
self.partTwoValue = partTwo;
[self updatePrimaryKey];
}
- (NSString*)partOne
{
return self.partOneValue;
}
- (NSString*)partTwo
{
return self.partTwoValue;
}
- (void)updatePrimaryKey
{
self.compositeKey = [NSString stringWithFormat:@"%@ <><><> %@", self.partOne, self.partTwo];
}
+ (NSString *)primaryKey
{
return @"compositeKey";
}
+ (RLMResults *)objectsWhere:(NSString *)predicateFormat args:(va_list)args {
predicateFormat = [predicateFormat stringByReplacingOccurrencesOfString:@"partOne" withString:@"partOneValue"];
predicateFormat = [predicateFormat stringByReplacingOccurrencesOfString:@"partTwo" withString:@"partTwoValue"];
return [self objectsWithPredicate:[NSPredicate predicateWithFormat:predicateFormat arguments:args]];
}
+ (RLMResults *)objectsInRealm:(RLMRealm *)realm where:(NSString *)predicateFormat args:(va_list)args {
predicateFormat = [predicateFormat stringByReplacingOccurrencesOfString:@"partOne" withString:@"partOneValue"];
predicateFormat = [predicateFormat stringByReplacingOccurrencesOfString:@"partTwo" withString:@"partTwoValue"];
return [self objectsInRealm:realm withPredicate:[NSPredicate predicateWithFormat:predicateFormat arguments:args]];
}
@end
单位测试:
- (void)testCompositeObject
{
CompositeKeyObject* object = [[CompositeKeyObject alloc] init];
object.partOne = @"ONE";
object.partTwo = @"TWO";
RLMRealm* realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
[realm addObject:object];
}];
XCTAssertNotNil([CompositeKeyObject objectForPrimaryKey:@"ONE <><><> TWO"]);
object = [[CompositeKeyObject alloc] init];
object.partOne = @"ONE";
object.partTwo = @"TWO";
[realm transactionWithBlock:^{
XCTAssertThrows([realm addObject:object]);
}];
}
- (void)testCompositeObject2
{
CompositeKeyObject* object = [[CompositeKeyObject alloc] initWithValue:@{@"partOne": @"ONE", @"partTwo": @"TWO"}];
RLMRealm* realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
[realm addObject:object];
}];
XCTAssertNotNil([CompositeKeyObject objectForPrimaryKey:@"ONE <><><> TWO"]);
object = [[CompositeKeyObject alloc] initWithValue:@{@"partOne": @"ONE", @"partTwo": @"TWO"}];
[realm transactionWithBlock:^{
XCTAssertThrows([realm addObject:object]);
}];
}