目标C:class init和block?
是否有可能,例如,在View Controller的init方法中使用块作为完成处理程序,以便父视图控制器能够填充块中的细节,而无需创build自定义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];
在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方法(并且必须为每个可能的初始化写一个)。
这东西不好吗? 会有保留周期吗?
你在使用块时看到了哪些优势? 初始化器通常用于设置实例的私有状态。 这个私有状态不能从该块中访问,因为该块在其他地方被实现。
如果你只使用公共属性,为什么不在初始化后设置呢?
SubViewController *vc = [[SubViewController alloc] initWithNibName:nil bundle:nil]; vc.property1 = NO; vc.property2 = [NSArray array]; vc.property3 = SomeEnumValue; vc.delegate = self;
这正是块版本(没有麻烦)。
这东西不好吗? 会有保留周期吗?
不,但是我会因为架构的原因而放弃你的build议:你要么破坏类的封装,要么没有获得任何优势,而只是在块初始化之后做什么。
问题是:
- 这种方式有什么好处?
- 你能够pipe理这个代码有效吗?
请注意,当程序不断增加时,将会添加新的调用级别,这会使您的代码难于阅读,维护,扩展或开发。 考虑未来的子类化,以及将来如何debugging这些代码以find一些不匹配的值。 块可以使你的代码更快,但是委托模式会使你的代码变得干净并且在一个线程中运行,这在未来很容易维护,这对专业程序员来说是真正的价值。
你可以定义你的
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil completionHandler:(void (^)(id newObj))block;
方法在UIViewController
类别中; 从那里你可以调用initWithNib
,然后在刚分配的self
上执行完成块:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil completionHandler:(void (^)(id newObj))block { if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { block(self); } return self; }
我认为这应该工作正常。
这是可能的,不存在retain
问题。 一切都将在同一个线程上同步调用。
但不这样做的简单方法有什么好处 – 在init
之后调用另一个方法,例如
MyController* controller = [[[MyController alloc] init] autorelease]; [self updateController:controller];
代码是否被init
方法调用?
一般来说,我会build议创build单独的init...
方法,如果你想以不同的方式初始化对象。
我真的不知道你为什么会采取这种做法(除非你想得到警方的关注)。 这不是一个好主意 。
你的控制器可以定义一个返回一个实例的函数或方法,代之以它想要的方式初始化。
- 添加颜色select器到iOS应用程序
- 在iOS中的UITextView的选定文本上应用富文本格式
- iOS 7 UIWebView 304caching错误,空白页面
- 快速停止后台任务
- 如何使用PureLayout摆脱情节提要和AutoLayout?
- Swift中的cocoa豆和领域
- xcodebuild失败clang:错误没有这样的文件或目录:
- 使用Cocoa Pod导入Google Analytics iOS SDK时出错
- 如果在设备的Accessiblity设置中未启用SpeakSelection,则对于文本到语音使用AVSpeechSynthesizer / AVSpeechUtterance将不起作用