Bool值的自定义访问器

时间:2011-08-23 11:54:27

标签: objective-c ios core-data nsmanagedobject

TaskNSManagedObject后代。它有一个ivar checkedcheckedNSNumber的类型,其中包含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];。它仍然崩溃。怎么了?谢谢。

2 个答案:

答案 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;
}

您现在可以访问并将已选中的属性设置为布尔值。