iPad上nib中的UIView为空,而iPhone上不为空。

3
我有一个奇怪的问题,我的应用程序加载名为“LoginViewController”的NIB文件时发生了问题。该NIB文件中有一堆指向像这样放置在NIB文件中的UIView对象的输出口:

enter image description here

运行时,我动态地将这些UIView对象作为表视图中的标题放置。每个单独的UIView在此处(除了右侧带有UITableView的那个)都被设置为IBOutlet。每个名称当然都不同:
@property (strong, nonatomic) IBOutlet UIView *connectionInProgressView;

现在,在我的VC的viewDidLoad方法中,我遍历这四个不同的视图,并通过写入日志来确保它们存在:
NSLog(@"connection in progress view: %@", self.connectionInProgressView);

我的问题是:在iPad上,self.connectionInProgressView为nil,在iPhone上不是。无论平台如何,所有其他视图都不为nil并且已经实例化。我在iOS 5.0、5.1和6.1的模拟器上运行此应用程序。我可以在所有iPad模拟器上重现此问题。我的应用程序在iPhone上正常工作并加载带有旋转器的视图,但在iPad上无法加载该视图,因为它为nil!为什么!?
我尝试过以下方法:
  • 检查我的NIB的文件所有者是否指向正确的视图
  • self.connectionInProgressView没有指向任何其他IBOutlet
  • 检查所有其他子视图是否与有问题的视图以相同的方式连接。它们是。
  • 删除self.connectionInProgressView,并在删除其所有NIB连接后重新创建它。
  • 从视图中删除活动指示器,并仅加载一个带有UILabel的视图。没有成功,这不是活动指示器的问题。
  • 检查VC中是否有任何可能引用self.connectionInProgressView的代码。没有(除了viewDidUnload中的nil语句)。
  • 检查UINavigationControllerLoginViewController的AppDelegate的属性属性类型。
  • 在AppDelegate上保留LoginViewController的副本,尽管这似乎浪费时间并且在结果上没有任何区别。
<编辑2> 问题:如何加载VC
我有一个UINavigationController,它是我的AppDelegate上的一个属性。我在applicationDidFinishLaunchingWithOptions中分配了该UINavigationController,将我的VC作为根视图控制器传递给它。我在这时实例化VC。
// Create login/start up views
LoginViewController *loginViewController = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil];

self.loginViewNavigationController = [[UINavigationController alloc] initWithRootViewController:loginViewController];

if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
    self.loginViewNavigationController.modalPresentationStyle = UIModalPresentationFormSheet;

请注意,尽管我稍后在iPad上将 UINavigationController 作为模态表单表呈现(不确定是否对我的问题有所贡献),但这在iPhone上是可以工作的。
稍后在AppDelegate中,当不同的代理类抛出事件时,我会将这个包含VC的UINavigationController以模态方式呈现。我是这样做的:
if (self.loginViewNavigationController != nil) {

    [self.window.rootViewController presentViewController:self.loginViewNavigationController animated:YES completion:nil];
}

我正在疯狂地尝试确定为什么这个特定的视图拖放到我的NIB上并与所有其他视图一样被连接,但在iPad上为nil,而在iPhone上不是。
[编辑1] 在搜索重复问题时,我没有找到以下内容:A few IBOutlets pointing to nil 我不是一个人! 有任何想法吗?

你是否有针对 iPhone 和 iPad 的单独目标?如果是这样,这个 nib 是针对两者的吗?你只在这个 nib 上遇到了这个问题(在 iPad 上无法工作)吗?还是所有的 nib 都有这个问题? - Nitin Alabur
不,我正在构建通用二进制。该 NIB 仅针对一个目标。我只在这个特定的 NIB 中遇到了这个问题。 - Aaron
viewDidUnload从未被调用。摆脱它。 - matt
请展示实际导致nib加载的代码 - 它只是某个UIViewController的实例化吗? - matt
3个回答

5

由于您正在构建通用应用程序,请确认您是否创建了独立的NIB文件用于iPhone和iPad(通常为LoginViewController.xibLoginViewController~ipad.xib)。

或者,也许您认为您只有一个XIB文件,但是在某个时候,您有一个专门针对iPad的XIB文件被编译成了NIB文件,即使您在项目中删除了XIB文件,仍然存在专门针对iPad的编译后NIB文件。

无论如何,请尝试:

  • 清理项目,或者更好的方法是清理您的构建产品目录
  • 要执行后者,您可以删除Derived Data文件夹("组织器"窗口-> "项目"选项卡->在左侧选择您的项目->单击"Derived Data"旁边的"删除"按钮)
  • 从所有模拟器中删除您的应用程序,以确保
  • 再次构建和运行

如果这不起作用,则可以尝试一些想法来帮助您调试并确定问题是否与iPad使用不同的XIB文件相关:

  • 您可以尝试进行一些测试,例如修改另一个IBOutlet,例如从XIB中将其中一个其他不为nilIBOutlet断开,以便再次运行应用程序时,它应该被记录为nil。如果在iPhone模拟器上是nil(因为您刚刚断开了它),但仍然不是nil在iPad模拟器上,则绝对意味着您为iPhone和iPad使用了不同的XIB文件。
  • 您还可以更改XIB中正确连接到您的一个IBOutletUIView的颜色,并查看更改是否反映在iPhone和iPad上,或仅在iPhone上,请检查您正在编辑的XIB文件是否与iPad上使用的相同。

Ali - 我会仔细看一下你的建议。回答你的第一个问题,我有一个完全不同的表格单元大小问题,我认为可以通过连接一个ipad.xib来解决。我尝试了一下,但没有成功,然后我删除了ipad.xib。自那以后,我已经多次清理了项目,但都没有效果。 - Aaron
你也重置了模拟器吗? - Rog
@Rog - 你说的重置模拟器是什么意思?我在iOS开发方面还比较新,可能会漏掉一些显而易见的东西。 - Aaron
@Ali - 上述的1-3步骤解决了我的问题。我删除了Build Products目录,从每个模拟器中删除了应用程序,然后幽灵.xib问题就解决了。 - Aaron
1
干得好。这个问题困扰了很多人,包括经验丰富的Xcode用户:构建应用程序并不会删除以前版本中的应用程序内容,因此您真的不知道其中有什么。唯一的解决方法是清除所有内容。请参考我在这里的答案:https://dev59.com/cW025IYBdhLWcg3w7qjL#6247073 - matt
除了Matt的评论之外,重要的是确保在任何nib更改后加载干净的构建。通常情况下,在模拟器上进行的nib更改不会显示,除非进行清理/重置。 - Nitin Alabur

1

我遇到了类似的问题,清理了项目,删除了派生数据,确保我没有为iPad使用单独的xibs;但似乎都没起作用。结果发现我的问题非常简单。我是这样初始化我的视图控制器的:

// In Swift
let vc = MyViewController()

直接使用nibName不如:

let vc = MyViewController(nibName: "MyViewController", bundle: NSBundle.mainBundle())

由于我的空指针错误似乎只在iPad上测试时出现,所以我从未想过检查控制器的初始化方式。


0
对于这个具体的案例,我遇到了一个奇怪的东西。在 viewDidLoad 中,我让一个 UITextField 成为了第一响应者,并将 NSNotifications 钩入该 UITextField 来管理键盘框架等。但有趣的是,当通知在 viewDidLoad 中分发时,只有在 iPad 上,插座才为空(不像 iPhone)。奇怪。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接