2017-07-31 74 views
0

我使用生成器模式做这样的事情是否可以在init-called块中设置只读属性?

- (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在这里似乎没有什么不同。

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

+0

对于尚未初始化的对象('[self mutableCopy]')做一个可变副本意味着什么?另外,你知道'mutableCopy'不会神奇地让你的类的属性读写,对吧?你采用了'NSMutableCopying'并实现了'-mutableCopyWithZone:'?它有什么作用?最后,关于“我这样做的目的是不必为这个子类的每个子类重写init [...]是否有正确的方法来做到这一点?”,我会恭敬地说,不,没有正确的方法来做到这一点。这是一个坏主意。 –

回答

0

是的,你可以使用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:适用于所有类型i来自NSObject或仅符合NSKeyValueCoding协议的类型。

+0

纠正我,如果我错了,但不会在任何情况下工作,即使在该init块之外? – baguIO

+0

'self = [super init]'call – ninjaproger

+0

后,它将会无处不在。请注意,键值编码(这里使用的)不适用于所有类型。 – newacct

相关问题