当视图未将其自身添加到其子视图时,“无法将自身添加为子视图”崩溃(带有示例代码)

时间:2018-03-15 21:04:21

标签: swift uiview uiviewcontroller uinavigationcontroller uikit

我可以通过一个简单的项目(Github Project

重现这个问题

主题板有一个嵌入式ViewController,由初始NavigationController的segue转换。 Nav Controller是初始根控制器,并在故事板视图中指向。

AppDelegate类didFinishLaunchingWithOptions方法实例化另一个导航控制器并以编程方式添加根视图控制器:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    let mainvc = MainViewController()
    let mainnc = UINavigationController(rootViewController: mainvc)

    self.window?.rootViewController = mainnc
    self.window?.makeKeyAndVisible()

    // Override point for customization after application launch.
    return true
}

上面实例化的MainViewController具有以下代码。

class MainViewController : UITableViewController, UIAlertViewDelegate {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    convenience init() {
        self.init(nibName:nil, bundle:nil)
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let tableView = UITableView(frame:CGRect(x:0, y:0, width:self.view.bounds.size.width, height:self.view.bounds.size.height), style:.plain)
        self.tableView = tableView
        tableView.delegate = self
        tableView.dataSource = self
        tableView.separatorColor = UIColor(white:0.85, alpha:1)
        tableView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        tableView.register(UITableViewCell.self, forCellReuseIdentifier:"nephews")

        self.view.addSubview(tableView) // CRASH
    }

}

运行代码时,我得到了:

  

2018-03-15 13:35:57.083953-0700 CantAddSelfAsSubview [20953:14423557]   ***由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'无法将自己添加为子视图'

*** First throw call stack:
(
    0   CoreFoundation                      0x000000010957912b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x0000000105900f41 objc_exception_throw + 48
    2   CoreFoundation                      0x00000001095ee245 +[NSException raise:format:] + 197
    3   UIKit                               0x0000000106267582 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 122
    4   UIKit                               0x00000001062c6341 -[UITableView _addSubview:positioned:relativeTo:] + 127
    5   CantAddSelfAsSubview                0x0000000104fdf310 _T020CantAddSelfAsSubview20MyMainViewControllerC11viewDidLoadyyF + 1312
    6   CantAddSelfAsSubview                0x0000000104fdf6c4 _T020CantAddSelfAsSubview20MyMainViewControllerC11viewDidLoadyyFTo + 36
    7   UIKit                               0x000000010634546c -[UIViewController loadViewIfRequired] + 1235
    8   UIKit                               0x000000010638cffc -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 68
    9   UIKit                               0x000000010638d338 -[UINavigationController _startTransition:fromViewController:toViewController:] + 153
    10  UIKit                               0x000000010638e44f -[UINavigationController _startDeferredTransitionIfNeeded:] + 841
    11  UIKit                               0x000000010638f6d3 -[UINavigationController __viewWillLayoutSubviews] + 150
    12  UIKit                               0x00000001065ea4e2 -[UILayoutContainerView layoutSubviews] + 231
    13  UIKit                               0x000000010626ea6d -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1439
    14  QuartzCore                          0x000000010cb5e61c -[CALayer layoutSublayers] + 159
    15  QuartzCore                          0x000000010cb627ad _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 401
    16  QuartzCore                          0x000000010cae986c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 364
    17  QuartzCore                          0x000000010cb16946 _ZN2CA11Transaction6commitEv + 500
    18  UIKit                               0x00000001061b826a __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 141
    19  CoreFoundation                      0x000000010951c05c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    20  CoreFoundation                      0x000000010950083b __CFRunLoopDoBlocks + 203
    21  CoreFoundation                      0x0000000109500014 __CFRunLoopRun + 1300
    22  CoreFoundation                      0x00000001094ff889 CFRunLoopRunSpecific + 409
    23  GraphicsServices                    0x000000010bd069c6 GSEventRunModal + 62
    24  UIKit                               0x000000010619d5d6 UIApplicationMain + 159
    25  CantAddSelfAsSubview                0x0000000104fe2027 main + 55
    26  libdyld.dylib                       0x000000010a717d81 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

由于我没有向自己添加视图,因此问题似乎在其他地方。

我已经阅读过很多关于SO的评论,类似的问题,但没有repro代码。有些人担心动画未完成时NavController中存在错误。如何控制segue的动画,因为它由第一个导航控制器自动管理?

1 个答案:

答案 0 :(得分:3)

由于viewDidLoad中的代码不正确,self.viewself.tableViewtableView都是相同的视图。因此错误。

这是UITableViewController。它已经有了一个表视图。不要创建另一个。更新viewDidLoad,如下所示:

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.separatorColor = UIColor(white:0.85, alpha:1)
    tableView.register(UITableViewCell.self, forCellReuseIdentifier:"nephews")
}

您也不需要添加任何init方法。