Bool 值的自定义访问器

发布于 2024-11-30 23:56:17 字数 1059 浏览 0 评论 0原文

TaskNSManagedObject 后代。它有一个 ivar checkedchecked 是包装 BOOL 值的 NSNumber 类型。

工作访问:

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 check = task.checked; 以及 BOOL chcecked = [已检查任务];。它仍然崩溃。怎么了?谢谢。

Task is NSManagedObject descendant. It has an ivar checked. checked is type of NSNumber which wraps a BOOL value.

Working access:

BOOL chcecked = [task.checked boolValue];
task.checked = [NSNumber numberWithBool:YES];

But I want somethink like this:

BOOL checked = task.checked;
task.checked = YES;

So I did category with primitive accessors:

@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

But it does not work... I tried BOOL checked = task.checked; and also BOOL chcecked = [task checked];. It still crashes. What is wrong? Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苏大泽ㄣ 2024-12-07 23:56:17

self.checked 相当于[selfchecked]。因此 -(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 is equivalent to [self checked]. So -(BOOL)checked is getting stuck in an infinite loop calling itself.

The benefit of using NSNumber * accessors instead of primitive ones is that you can determine if the property has been set to true or false, or hasn't been set at all. In this case it may not matter, but in general it can be useful information to know.

Core Data dynamically generates accessors for you, so I would recommend something like:

@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
岛徒 2024-12-07 23:56:17

您不想创建原始访问器,而是创建自定义访问器。但是,您还应该声明原始访问器。尽管它可以与 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 属性并将其设置为布尔值。

You don't want to create primitive accessors, but custom accessors. However you should also declare primitive accessors. Even though it would work with valueForKey: and setValue:forKey:, according to Apples documentation primitive accessors are a lot faster than KVC.

In your Task.h file declare:

@property (nonatomic, assign) BOOL checked;

In your implementation declare the primitive accessor methods:

@interface Task (PrimitiveAccessors)
- (void)setPrimitveChecked:(NSNumber *)value;
- (NSNumber *)primitiveChecked;
@end

Finally implement the custom accessor methods:

- (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;
}

You can now access and set your checked property as a boolean.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文