什么时候设置XIBsockets属性?
我正在尝试使用xib文件实现inheritance。 是的,有点奇怪,但让我告诉你为什么。
我有一个类,我的许多视图控制器inheritance的SLBaseViewController。 当我想要一个子视图控制器时,我会以通常的方式创建它:
SLHomeViewController *controller = [[SLHomeViewController alloc] initWithNibName:@"SLHomeViewController" bundle:nil];
这很好用。 SLHomeViewController是一个SLBaseViewController(它是一个UIViewController)。
我这样做是因为我有其他视图控制器,我想inheritanceSLBaseViewController行为。 在我的例子中,我有一个在我的应用程序中常见的导航UI小部件,因此SLSceneViewControll也从SLBaseViewControllerinheritance,并且SLHomeViewController和SLSceneViewController都获得自定义导航小部件行为。
自定义导航窗口小部件还具有在SLBaseViewControllers中通用的位置信息。 所以我实现了一个穷人做xibinheritance的方法。
@interface SLBaseViewController : UIViewController @property (strong, nonatomic) IBOutlet UIView *navBarExtendedFPO;
并且inheritance在initWithNibName中完成
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { Class callingClass = [self class]; Class slBaseViewControllerClass = NSClassFromString (SL_BASE_VC_CLASS_NAME); if (callingClass != slBaseViewControllerClass) { SLBaseViewController *controller = [[SLBaseViewController alloc] initWithNibName:@"SLBaseViewController" bundle:nil]; // now load all the properties by hand self.navBarExtendedFPO = controller.navBarExtendedFPO; } } return self; }
如果我创建一个SLHomeViewController,则加载SLBaseViewController的xib,然后从中复制有趣的属性。 如果initWithNibName检测到它正在加载SLBaseViewController,它就什么也不做,阻止了无限循环。
当然,问题是出口属性尚未设定。 所以它只是复制零。
那么这些出口属性何时设定?
或者 – 有没有更好的方法来做我想做的事情? 在我手工复制属性之前,这一切看起来都很美好。 这对我来说似乎很脆弱。
(注意,我只使用iOS6解决方案。)
这是因为UIViewController的延迟初始化。
只有在调用view属性之后才会加载UIViewController的视图。
像那样:
controller.view
因此,在您的情况下,您可以在self.navBarExtendedFPO = controller.navBarExtendedFPO;
之前调用self.navBarExtendedFPO = controller.navBarExtendedFPO;
为了更清楚地解释视图生命周期,有一个例子:
在SLBaseViewController中有重写的方法, self.label
navBarExtendedFPO
XIB文件中定义的navBarExtendedFPO
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { NSLog(@"initWithNibName: view loaded - %d , IBOuttlet loaded - %d", [self isViewLoaded], self.label != nil); } return self; } - (void)loadView { NSLog(@"loadView1: view loaded - %d , IBOuttlet loaded - %d", [self isViewLoaded], self.label != nil); [super loadView]; NSLog(@"loadView2: view loaded - %d , IBOuttlet loaded - %d", [self isViewLoaded], self.label != nil); } - (void)viewDidLoad { NSLog(@"viewDidLoad1: view loaded - %d , IBOuttlet loaded - %d", [self isViewLoaded], self.label != nil); [super viewDidLoad]; NSLog(@"viewDidLoad2: view loaded - %d , IBOuttlet loaded - %d", [self isViewLoaded], self.label != nil); }
并且有创建SLBaseViewController的方法
SLBaseViewController *testController = [[SLBaseViewController alloc] initWithNibName:@"SLBaseViewController" bundle:nil]; NSLog(@"after initialization: view loaded - %d , IBOuttlet loaded - %d", [testController isViewLoaded], testController.label != nil); UIView * testView = testController.view; NSLog(@"after calling testView.view: view loaded - %d , IBOuttlet loaded - %d", [testController isViewLoaded], testController.label != nil);
所以,有我们的日志:
initWithNibName: view loaded - 0 , IBOuttlet loaded - 0 after initialization: view loaded - 0 , IBOuttlet loaded - 0 loadView1: view loaded - 0 , IBOuttlet loaded - 0 loadView2: view loaded - 1 , IBOuttlet loaded - 1 viewDidLoad1: view loaded - 1 , IBOuttlet loaded - 1 viewDidLoad2: view loaded - 1 , IBOuttlet loaded - 1 after calling testView.view: view loaded - 1 , IBOuttlet loaded - 1