Objective c 如何编写防止调用viewDidLoad的自定义初始值设定项?
我想为Objective c 如何编写防止调用viewDidLoad的自定义初始值设定项?,objective-c,uiviewcontroller,initialization,ios5,Objective C,Uiviewcontroller,Initialization,Ios5,我想为UIViewController构建一个定制的init方法,但是在互联网上,特别是在中,我对指定的初始值设定者感到困惑 我有一个UIViewController的子类,其中有两个初始值设定项: - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]
UIViewController
构建一个定制的init方法,但是在互联网上,特别是在中,我对指定的初始值设定者感到困惑
我有一个UIViewController
的子类,其中有两个初始值设定项:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if ( self ) {
}
return self;
}
- (id) initWithFilename:(NSString *)aFilename {
self = [self initWithNibName:@"WallpaperDetailsViewController" bundle:nil];
if ( self ) {
self.filename = aFilename;
}
return self;
}
然后我有一个viewDidLoad
方法,它根据filename
属性自定义视图:
- (void)viewDidLoad {
[super viewDidLoad];
// Create a UIImageView to display the wallpaper
self.wallpaper = [[UIImageView alloc] initWithImage:[UIImage imageNamed:self.filename]];
// ...
}
在另一个UIViewController
中,我进行以下调用:
WallpaperDetailsViewController *detailsViewController = [[WallpaperDetailsViewController alloc] initWithFilename:@"foobar.png"];
[[self navigationController] pushViewController:detailsViewController animated:YES];
结果是调用viewDidLoad
是由于[self initWithNibName:][/code>没有初始化UIImageView
,因为self.filename
为空
根据其他SO问题和答案,这应该是预期的行为。我不确定这一点,因为我在iOS 5之前的其他项目中有自己的经验。我的问题是:
如何确保viewDidLoad:
在initWithFilename:
之后调用,而不是在initWithFilename:
和initWithNibNameOrNil:bundle:
之间调用
如果不可能,如何实现接收自定义数据的初始值设定项方法来创建和自定义视图
谢谢 为什么不为filename属性使用一个自定义setter,在每次设置文件名时初始化UIImage
或者,也可以从ViewWillDisplay中的filename属性设置UIImage:而不是viewDidLoad。首先,不建议在初始值设定项中使用点语法。请参阅以下内容,了解一些有益的讨论:
其次,您可以做的是在初始值设定项中指定图像。所以你可以按照
- (id) initWithFilename:(NSString *)aFilename {
self = [self initWithNibName:@"WallpaperDetailsViewController" bundle:nil];
if ( self ) {
filename = [aFilename retain];
wallpaper = [[UIImageView alloc] initWithImage:[UIImage imageNamed:aFileName]];
}
return self;
}
这将允许您在调用viewDidLoad之前将所有内容设置好并处于良好状态
祝你好运 您不需要initWithNibName:bundle:
的空实现。此外,这里的类似乎正在将其指定的初始值设定项设置为initWithFilename:
如果这是真的,initWithFilename:
应该调用超类的D.I.:
- (id) initWithFilename:(NSString *)aFilename {
// Call super's designated initializer
self = [super initWithNibName:@"WallpaperDetailsViewController"
bundle:nil];
if ( self ) {
self.filename = aFilename;
}
return self;
}
规则是类中的所有初始值设定项都应该调用类的D.I.,而D.I.本身应该调用超类的D.I
从您发布的内容来看,还不完全清楚为什么在初始值设定项完成之前调用loadView:
。Logancautrell建议在视图加载方法中设置断点的评论很好。我发现了这个问题
wallperdetailsviewcontroller
不是直接从UIViewController
继承,而是从我实现的另一个自定义UIViewController
继承
问题是什么?我已经在父对象的initWithNibName
方法中初始化了一个子视图,而不是遵循延迟加载技术,在viewDidLoad
中进行初始化。当wallperdetailsviewcontroller
调用其父初始值设定项时,它变得混乱,导致viewDidLoad
无法正常工作
解决方案是什么?我将父类中的每个子视图初始化都移动到了它的viewDidLoad
方法,并保持了wallpDetailsViewController
的原始实现完好无损。现在一切都按预期进行
感谢@Josh Caswell和@logancautrell文件名是如何定义的?声明的属性或自定义附件?文件名
的定义类似于@property(强、非原子)NSString*文件名
在@interface
的壁纸详细信息viewcontroller
声明中,您的init代码中发生了导致加载视图的事件。在视图中设置一个断点并查看它为什么会被提前调用。当然,这是另一种解决方案,但我想了解其行为:)实际上我是这么想的,但在这种情况下它对我不起作用。这就是为什么我在问这个问题之前把头撞到墙上的原因。UIImageView
没有正确创建,因为viewDidLoad
是在设置self.filename=aFilename
之前调用的。我想这是有道理的,因为在这种情况下[super initWithNibName:@“…”bundle:nil];]
完全等同于在self
上调用它。不需要在视图控制器的初始化方法中创建图像视图。事实上,如果VC收到内存警告,这可能会导致问题。最好坚持惰性加载模式,只在需要时分配它,在loadView:
或viewDidLoad:
很高兴你找到了它。我想我的答案有点旁敲侧击,但很明显,解决方案在于代码,而不是你发布的代码。