是否可以在init-called blocks中设置只读属性?

时间:2017-07-31 16:22:48

标签: objective-c objective-c-blocks

我正在使用构建器模式执行类似这样的操作

- (instancetype)initUsingBlock:(void(^)(id mutableCopy))block
{
    self = [super init];
    if (self && block)
    {
        __block id mutableInstance = [self mutableCopy];
        block(mutableInstance);
        self = [mutableInstance copy];
    }
    return self;
}

并使用块设置属性。 我这样做的目的是不必为这个的每个子类重写init但是这些属性是readonly并试图将它们设置在块 - 在另一个类中调用 - 引发错误。有没有正确的方法来做到这一点? __block似乎没有什么区别。

编辑:所以,由于这里的评论,我意识到继续我想要做的事情并不是一个好主意,所以我完全放弃了构建模式,但我仍然不知道是否可能。

1 个答案:

答案 0 :(得分:0)

是的,你可以使用NSObject的{​​{3}}方法来实现,但实际上这不是一个好的做法:

@interface TestClass : NSObject

@property (copy, nonatomic,readonly) NSString *testProperty;

@end

@implementation TestClass

- (instancetype)initUsingBlock:(void(^)(id instance))block {
    if (self = [super init]) {
        block(self);
    }
    return self;
}

@end

...

TestClass *test = [[TestClass alloc] initUsingBlock:^(id instance) {
    if ([instance respondsToSelector:@selector(testProperty)]) {
        [instance setValue:@"It's working" forKey:@"testProperty"];
    }
}];
NSLog(@"%@", test.testProperty);

或者:

TestClass *test = [[TestClass alloc] init];
if ([test respondsToSelector:@selector(testProperty)]) {
    [test setValue:@"It's working" forKey:@"testProperty"];
}

PS:适用于从NSObject继承的所有类型或仅符合NSKeyValueCoding协议的类型。