尝试在 Swift 中访问无主引用总是会导致应用程序崩溃
Posted
技术标签:
【中文标题】尝试在 Swift 中访问无主引用总是会导致应用程序崩溃【英文标题】:Trying to access an unowned reference in Swift always causes the app to crash 【发布时间】:2014-06-14 07:18:44 【问题描述】:在 WWDC 2014 之前,我正在学习 Objective-C。我创建了一个“电梯模拟器”应用程序,它的存在只是为了我的学习目的。当您单击七个按钮中的一个时,它会关闭电梯门(动画),一次向所选级别移动一层(如文本标签和按钮颜色所示),然后重新打开门。
随着 WWDC 和 Swift 的发布,我正在尝试在 Swift 中重新创建这个应用程序。到目前为止,我发现 Swift 更好用,但我遇到了一个关于无主引用的主要障碍。该应用程序启动良好,直到我实现了文本标签和按钮颜色的功能,以在应用程序启动时根据 Elevator 模型的属性进行设置。实现这些功能后,应用总是在启动时崩溃。
最终,我将问题缩小到从视图控制器到 Elevator 模型的任何调用中。在注释掉对我的视图控制器方法的调用以更新界面后,应用程序再次正常启动,我可以通过尝试调用初始化程序来确认问题在于调用电梯模型。以下代码 sn-ps 重现了该问题:
应用代理:
var window: UIWindow?
let mainElevator = Elevator()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool
window = UIWindow(frame: UIScreen.mainScreen().bounds)
mainElevator.view = ViewController(elevator: mainElevator)
window!.rootViewController = mainElevator.view
window!.makeKeyAndVisible()
return true
电梯(型号):
class Elevator: NSObject
var view: ViewController?
var currentLevel = 1
var newLevel: Int?
视图控制器:
class ViewController: UIViewController
unowned let elevator: Elevator
init(elevator: Elevator)
self.elevator = elevator
super.init(nibName: nil, bundle: nil)
//self.elevator.currentLevel = 3
注意:我已经在这些类中发出了其他方法,因为它们似乎对问题没有影响。我通过使用 Person 和 CreditCard 示例(Apple 用作示例)创建了一个类似的场景来确认这一点,这些示例仅由我在上面粘贴的部分组成。
ViewController 的最后一行注释掉后,应用程序启动正常(显示基于 loadView() 和 viewDidLoad() 的视图),但如果我取消注释,应用程序就会崩溃。如果我将引用类型更改为弱和可选,它也可以正常工作,但它不应该是弱的、可选的、 或 变量。电梯将永远存在(但不一定是视图,由于多任务处理),它应该是恒定的。这正是 Apple 在 Person/CreditCard 场景中描述的那种情况。
另外,如果我从最后一个齿中删除 self.(因此使用本地版本的 elevator),它可以正常工作。所以模型并没有被释放,只是无主引用不起作用。
编辑:崩溃报告
libswift_stdlib_core.dylib`_swift_abortRetainUnowned:
0x1001c3980: pushq %rbp
0x1001c3981: movq %rsp, %rbp
0x1001c3984: leaq 0x176a7(%rip), %rax ; "attempted to retain deallocated object"
0x1001c398b: movq %rax, 0x792ce(%rip) ; gCRAnnotations + 8
0x1001c3992: int3
0x1001c3993: nopw %cs:(%rax,%rax) Thread 1: EXC_BREAKPOINT (code=EXT_1386_BPT, subcode=0x0)
【问题讨论】:
您看到了什么样的崩溃消息(感谢目前 Xcode 6 的长镜头...) 我已更新问题以包含来自 Xcode 的报告。这是你要求的吗? 是的,我就是这个意思。 【参考方案1】:我猜这是一个错误。
如果您的 Elevator 类没有从 NSObject 继承,它可以工作。否则你会收到很长的错误信息。
class Elevator
var view: ViewController?
var currentLevel = 1
var newLevel: Int?
【讨论】:
嗯,这很有趣。是的,它解决了问题。我记得苹果说过“你不需要继承 NSObject,但你可以”。我猜这样做的原因是在 Objective-C 特定函数中使用该类?我只是想知道子类化是否更好。 @JamesFletcher 有人已经在 SO 中问过这个问题:***.com/questions/24057525/…以上是关于尝试在 Swift 中访问无主引用总是会导致应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章