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

is it possible to set readonly properties within init-called 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;
}

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

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

是的,您可以使用 NSObject[setValue:forKey:] 方法来做到这一点,但实际上这样做并不是一个好的做法:

@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 协议的类型。