布尔值的自定义访问器
Posted
技术标签:
【中文标题】布尔值的自定义访问器【英文标题】:Custom Accessors For Bool Values 【发布时间】:2011-08-23 11:54:27 【问题描述】: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];
。它仍然崩溃。怎么了?谢谢。
【问题讨论】:
【参考方案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 小部件背景透明?