目标C:带有块的init初始化?

目标C:带有块的init初始化?

问题描述:

比如说可以在View Controller的init方法中使用一个块作为完成处理程序,以便父视图控制器能够在一个块中填充细节,而不必创建自定义initWithNibName:andResourceBundle:andThis :andThat:对于每个可能的属性?

Is it possible to, say, use a block as a completion handler in a View Controller's init method so that the parent view controller is able to fill in the details in a block without having to create a custom initWithNibName:andResourceBundle:andThis:andThat: for each possible properties ?

// ... 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];

在SubViewController.m中:

in 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;
}

代替

// ... 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];

使用

- (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;
}

与调用预定义的init方法相比,我可以在主控制器中做任何我想做的事情(并且必须为每个可能的初始化编写一个方法).

So that I can do whatever I want in the main controller vs calling a predefined init method (and having to write one for each possible initialization).

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

Is it something bad ? will there be retain cycles ?

您在使用块时看到了哪些优势?初始化程序通常用于设置实例的 private 状态.由于该块是在其他地方实现的,因此无法从该块访问此私有状态.

Which advantages do you see in using a block? The initializer is commonly used to set up private state of the instance. This private state could not be accessed from the block since the block is implemented somewhere else.

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

If you only use public properties why not setting them up after initialization?

SubViewController *vc = [[SubViewController alloc] initWithNibName:nil bundle:nil];
vc.property1 = NO;
vc.property2 = [NSArray array];
vc.property3 = SomeEnumValue;
vc.delegate = self;

这正是街区版本的功能(没有麻烦).

That's exactly what the block version does (without the hassle).

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

Is it something bad ? will there be retain cycles ?

否,但是出于架构原因,我会驳回您的主张:您正在破坏类的封装,或者仅在初始化后执行该块的操作就没有任何好处.

No, but I would dismiss your proposition for architectural reasons: You are either breaking encapsulation of the class or do not gain any advantage over just doing what the block does after initialization.