Task
是NSManagedObject
后代。它有一个ivar checked
。 checked
是NSNumber
的类型,其中包含BOOL
值。
工作访问权限:
BOOL chcecked = [task.checked boolValue];
task.checked = [NSNumber numberWithBool:YES];
但我想要这样想:
BOOL checked = task.checked;
task.checked = YES;
所以我用原始访问器做了类别:
@interface Task (PrimitiveAccessors)
- (void)setChecked:(BOOL)checked;
- (BOOL)checked;
@end
@implementation Task (PrimitiveAccessors)
- (void)setChecked:(BOOL)checked
{
[self willChangeValueForKey:@"checked"];
self.checked = [NSNumber numberWithBool:checked];
[self didChangeValueForKey:@"checked"];
}
- (BOOL)checked
{
[self willAccessValueForKey:@"checked"];
BOOL returnValue = [self.checked boolValue];
[self didAccessValueForKey:@"checked"];
return returnValue;
}
@end
但它不起作用......我尝试了BOOL checked = task.checked;
和BOOL chcecked = [task checked];
。它仍然崩溃。怎么了?谢谢。
答案 0 :(得分:3)
self.checked
相当于[self checked]
。所以-(BOOL)checked
陷入无限循环调用自身。
使用NSNumber *访问器而不是原始访问器的好处是,您可以确定该属性是设置为true还是false,或者根本没有设置。在这种情况下,它可能无关紧要,但一般来说,知道它可能是有用的信息。
Core Data为您动态生成访问器,因此我建议使用以下内容:
@interface Task : NSManagedObject
{}
@property (nonatomic, retain) NSNumber * checked;
- (BOOL) taskIsChecked;
- (void) setTaskIsChecked:(BOOL)isChecked;
@end
@implementation Task
@dynamic checked;
- (BOOL) taskIsChecked
{
return [self.checked boolValue];
}
- (void) setTaskIsChecked:(BOOL)isChecked
{
self.checked = isChecked ? (NSNumber *)kCFBooleanTrue : (NSNumber *)kCFBooleanFalse;
}
@end
答案 1 :(得分:1)
您不想创建原始访问者,而是创建自定义访问者。但是,您还应该声明原始访问器。尽管它适用于valueForKey:
和setValue:forKey:
,但根据Apples文档,原始访问器比KVC快得多。
在Task.h文件中声明:
@property (nonatomic, assign) BOOL checked;
在您的实现中声明原始访问器方法:
@interface Task (PrimitiveAccessors)
- (void)setPrimitveChecked:(NSNumber *)value;
- (NSNumber *)primitiveChecked;
@end
最后实现自定义访问器方法:
- (void)setChecked:(BOOL)flag
{
[self willChangeValueForKey:@"checked"];
[self setPrimitiveChecked:[NSNumber numberWithBool:flag]];
[self didChangeValueForKey:@"checked"];
}
- (BOOL)checked
{
[self willAccessValueForKey:@"checked"];
flag = [[self primitiveChecked] boolValue];
[self didAccessValueForKey:@"checked"];
return flag;
}
您现在可以访问并将已选中的属性设置为布尔值。