【问题标题】: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];。它仍然崩溃。怎么了?谢谢。

【问题讨论】:

    标签: objective-c ios core-data nsmanagedobject


    【解决方案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 属性设置为布尔值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-14
      • 2021-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-29
      • 2020-09-11
      • 2015-01-05
      相关资源
      最近更新 更多