gpt4 book ai didi

ios - 如何在 Swift 中对子类化的 UIViewController 进行类型转换?

转载 作者:搜寻专家 更新时间:2023-10-31 08:16:00 25 4
gpt4 key购买 nike

我正在尝试使用 Storyboard快速测试 UITableViewController 的子类。我能够获得对 View Controller 的引用并将其记录下来,但我无法将其类型转换为我正在尝试测试的类,因此我无法访问方法、属性等。

获取类实例的正确方法是什么?

测试场景:

import XCTest
import UIKit
class GameListControllerTest: XCTestCase {
var storyboard = UIStoryboard(name: "Main", bundle: nil)
var _sut: AnyObject?
var sut: AnyObject {
if(_sut?) {
return _sut!
}
_sut = storyboard.instantiateViewControllerWithIdentifier("GameListController")
return _sut!
}
override func setUp() {
super.setUp()
println()
println("=================================")
println("sut \(sut)")
println("view \(sut.view)")
println("=================================")

}
func testInstance() {
var vc1 = sut as UITableViewController
var vc2 = sut as? GameListController
println()
println("=================================")
println("VC1 \(vc1)")
println("VC2 \(vc2)")
println("=================================")
}
}

输出:

XCTestOutputBarrierTest Suite '_TtC15mytabletopTests22GameListControllerTest' started at 2014-06-16 06:13:30 +0000
XCTestOutputBarrierTest Case '-[_TtC15mytabletopTests22GameListControllerTest testInstance]' started.
XCTestOutputBarrier
=================================
sut <_TtC10mytabletop18GameListController: 0xb338d50>
view <UITableView: 0xc033800; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0xb344960>; layer = <CALayer: 0xb33c7d0>; contentOffset: {0, 0}; contentSize: {480, 0}>
=================================

=================================
VC1 <_TtC10mytabletop18GameListController: 0xb338d50>
VC2 nil
=================================
Test Case '-[_TtC15mytabletopTests22GameListControllerTest testInstance]' passed (0.007 seconds).
XCTestOutputBarrierTest Suite '_TtC15mytabletopTests22GameListControllerTest' passed at 2014-06-16 06:13:30 +0000.
Executed 1 test, with 0 failures (0 unexpected) in 0.007 (0.010) seconds

如果我尝试强制类型转换(sut as GameListController),我会得到一个运行时异常。

最佳答案

这是正在发生的事情。我花了好几天才弄明白,但我的问题是我的类是如何导出到目标的:

File Inspector Target Membership Incorrect vs. Correct

这导致了我的类的两个二进制副本,一个在应用程序目标中,另一个在测试目标中。如果我们更多地关注日志,我们可能会注意到:

Test Case '-[_TtC15mytabletopTests22GameListControllerTest testInstance]'

上面是测试方法testInstance,它是mytabletopTests 执行上下文的一部分。现在让我们看一下从 Storyboard 中提取的实例:

sut  <_TtC10mytabletop18GameListController: 0xb338d50>

这又在 mytabletop 上下文中运行。这解释了为什么测试无法类型转换为 GameListController。它知道的 GameListController 是在测试目标中编译的那个。

由于从测试目标中删除该类会使我的测试用例不知道该类,现在我需要将我的应用目标导入到测试用例中:

import XCTest
import UIKit
import mytabletop // LINE ADDED

class GameListControllerTest: XCTestCase {

现在,测试可以访问的唯一 GameListController 是 Storyboard 正在实例化的那个,我终于可以对其进行类型转换了。这是新的测试用例:

import XCTest
import UIKit
import mytabletop

class GameListControllerTest: XCTestCase {
let sut: GameListController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("GameListController") as GameListController

override func setUp() {
super.setUp()
UIApplication.sharedApplication().keyWindow.rootViewController = sut
XCTAssertNotNil(sut.view)
}

func testInstance() {
XCTAssertNotNil(sut)
XCTAssertNotNil(sut.tableView) // UITableViewController property
XCTAssertNotNil(sut.store) // instance property
XCTAssertNotNil(sut.someButton) // outlet
}
}

现在我可以在实例初始化期间正确进行类型转换(滚动查看 as GameListController)。为了强制正确绑定(bind)所有 socket 并根据正在运行的设备呈现 subview ,我们可以使 View Controller 成为应用程序的 rootViewController 并从中拉取 View ,如在上面的 setUp 函数中看到。甚至 myCustomOutlet 现在也能正常工作。

关于ios - 如何在 Swift 中对子类化的 UIViewController 进行类型转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24237609/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com