目标C:使用块的init类?

Dav*_*urt 5 objective-c ios objective-c-blocks

例如,是否可以在View Controller的init方法中使用块作为完成处理程序,以便父视图控制器能够填充块中的详细信息而无需创建自定义initWithNibName:andResourceBundle:andThis:andThat:对于每个可能的属性?

// ... in the didSelectRowAtIndexPath method of the main view controller :
SubViewController *subviewController = [[SubViewController alloc] initWithNibName:nil bundle:nil completionHandler:^(SubViewController * vc) {
    vc.property1 = NO;
    vc.property2 = [NSArray array];
    vc.property3 = SomeEnumValue;
    vc.delegate = self;
}];
[self.navigationController pushViewController:subviewController animated:YES];
[subviewController release];
Run Code Online (Sandbox Code Playgroud)

在SubViewController.m中:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil completionHandler:(void (^)(id newObj))block {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        block(self);
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

代替

// ... in the didSelectRowAtIndexPath method of the main view controller :
SubViewController *subviewController = [[SubViewController alloc] initWithNibName:nil bundle:nil andProperty1:NO andProperty2:[NSArray array] andProperty3:SomeEnumValue andDelegate:self];
[self.navigationController pushViewController:subviewController animated:YES];
[subviewController release];
Run Code Online (Sandbox Code Playgroud)

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil andProperty1:(BOOL)p1 andProperty2:(NSArray *)p2 andProperty3:(enum SomeEnum)p3 andDelegate:(id<MyDelegateProtocol>)myDelegate {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
       self.property1 = p1;
       self.property2 = p2;
       self.property3 = p3;
       self.delegate = myDelegate;
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

因此,我可以在主控制器中执行任何操作,而不是调用预定义的init方法(并且必须为每个可能的初始化编写一个).

这有什么不好吗?会有保留周期吗?

Nik*_*uhe 3

您认为使用块有哪些优点?初始化程序通常用于设置实例的私有状态。无法从块访问此私有状态,因为该块是在其他地方实现的。

如果您只使用公共属性,为什么不在初始化后设置它们呢?

SubViewController *vc = [[SubViewController alloc] initWithNibName:nil bundle:nil];
vc.property1 = NO;
vc.property2 = [NSArray array];
vc.property3 = SomeEnumValue;
vc.delegate = self;
Run Code Online (Sandbox Code Playgroud)

这正是块版本所做的(没有麻烦)。

难道是有什么不好的事情吗?会有保留周期吗?

不,但出于架构原因,我会驳回您的建议:您要么破坏了类的封装,要么与初始化后执行块所做的事情相比没有获得任何优势。