布尔值的自定义访问器

Posted

技术标签:

【中文标题】布尔值的自定义访问器【英文标题】:Custom Accessors For Bool Values 【发布时间】:2011-08-23 11:54:27 【问题描述】:

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];。它仍然崩溃。怎么了?谢谢。

【问题讨论】:

【参考方案1】:

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

【讨论】:

嗯...我希望它会覆盖自动生成的访问器。您的解决方案没有我想要的那么好,但如果这是唯一的方法,那就谢谢您了! 您可能只使用您的代码,但在您使用self.checked 的地方替换[self primitiveChecked],它应该可以正常工作。我只是不喜欢覆盖自动访问器。【参考方案2】:

您不想创建原始访问器,而是自定义访问器。但是,您还应该声明原始访问器。尽管它可以与 valueForKey:setValue:forKey: 一起使用,但根据 Apple 的文档,原始访问器比 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;

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

【讨论】:

以上是关于布尔值的自定义访问器的主要内容,如果未能解决你的问题,请参考以下文章

如何让 qt 设计器自定义 QOpenGLWidget 小部件背景透明?

配置 WSO2 API 管理器自定义身份验证器和声明

为啥我的自定义 JSONEncoder.default() 忽略布尔值?

自定义类中的自定义对话框返回布尔值

Pandas 中的自定义布尔过滤?

Hadoop Partitioner 中的自定义计数器