我正在使用现有代码,我看到我们使用performSegueWithIdentifier:sender:推送一些viewController,然后我们将数据传递给目标viewController:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.destinationViewController isKindOfClass:[DetailsViewController class]]) {
DetailsViewController *detailsVC = (DetailsViewController *)segue.destinationViewController;
detailsVC.detailsData = someData;
}
然后想象我们在destinationViewController中有一个自定义的setDetailsData setter:
- (void)setDetailsData:(NSDictionary *)detailsData {
_detailsData = detailsData;
// other data customisation stuff
// Then we need to assign initial values to outlets
// The view is not loaded yet, so we are forcing to initialise this view. This will result in viewDidLoad being called
self.view.userInteractionEnabled = YES;
// Set outlet values
self.firstNameLabel.text = [_detailsData …];
self.lastNameLabel.text = [_detailsData …];
}
在prepareForSegue内执行setDetailsData:时,尚未调用destinationViewController的有趣部分viewDidLoad。所以我们不能为这些出口分配值,因为它们尚未初始化(零)。因此,为了使其工作,有一点点黑客:
self.view.userInteractionEnabled = YES;
这会强制初始化视图和插座。我同意,拥有这样的自定义设置器既可以用于内部数据的定制,也可以分配出口很方便(一切都在一个地方),但我担心这会破坏正常的视图初始化流程。我们应该只传递数据。应在viewDidLoad方法中单独分配出口的值。你对此有什么看法,这是正常的吗?我无法在Apple文档中找到任何限制,但仍然对此表示怀疑。
答案 0 :(得分:1)
请记住将您的财产设置为强大:
@property (strong, nonatomic) NSDictionary * detailsData;
并在viewDidLoad中进行UI更新。
答案 1 :(得分:1)
我不喜欢它,但是如果它有效的话就可以了!
我的意思是,你的代码工作且没有错误(假设它不是)的事实证明技术是解决这个小问题的可行方法。
但另一方面,这是我个人的观点,它使代码看起来很脏。当你看到那行代码时
self.view.userInteractionEnabled = YES;
你会认为“哦,这必须使用户能够与UI进行交互,默认情况下必须禁用它”,但是没有,这是一个初始化UI的黑客行为。因为我们经常复制粘贴我们自己的代码,所以我们养成了一个坏习惯。
答案 2 :(得分:0)
由于您已经保存了对详细信息数据的引用,我的偏好(以及“规范”)将视图初始化(self.firstName.test ....)移动到viewDidLoad中。这样你就可以保证视图已被加载但尚未显示并且你不再依赖“self.view.userInteractionEnabled = ...”的副作用。如果你真的坚持在那里做,至少使用“if(!self.isViewLoaded)[self loadView]”