簡體   English   中英

試圖訪問Swift中的無主引用總是會導致應用程序崩潰

[英]Trying to access an unowned reference in Swift always causes the app to crash

在WWDC 2014之前,我學習了Objective-C。 我創建了一個“Elevator Simulator”應用程序,僅僅是為了我的學習目的。 當您單擊七個按鈕中的一個時,它會關閉電梯門(動畫),一次向所選級別移動一級(如文本標簽和按鈕着色所示),然后重新打開門。

繼WWDC和Swift宣布之后,我正試圖在Swift中重新創建這個應用程序。 到目前為止,我發現Swift更適合使用,但我遇到了一個涉及無主參考的主要障礙。 應用程序啟動正常,直到我實現了文本標簽和按鈕着色的功能,以根據應用程序啟動時Elevator模型的屬性進行設置。 實現這些功能后,應用程序始終在啟動時崩潰。

最終,我將問題范圍縮小到從視圖控制器到Elevator模型的任何調用。 在注釋掉我的視圖控制器方法的調用以更新界面后,應用程序再次啟動正常,我可以確認問題是僅通過嘗試調用初始化程序來調用Elevator模型。 以下代碼片段重現了此問題:

應用代表:

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
    }
}

注意:我在這些類中發布了其他方法,因為它們似乎沒有對該問題產生影響。 我已經通過使用PersonCreditCard示例(用作Apple的示例)創建了一個類似的場景來確認這一點,該示例僅包含我上面粘貼的部分。

隨着最后一行ViewController被注釋掉,應用程序啟動正常(顯示基於loadView()viewDidLoad()的視圖),但如果我取消注釋它,應用程序崩潰。 如果我將引用類型更改為弱和可選,它也可以正常工作,但它不應該是弱,可選變量。 電梯將始終存在(但不一定是視圖,由於多任務),它應該是不變的。 這正是Apple在Person / CreditCard場景中描述的那種情況。

另外,如果我刪除自己。 從最后一個齒輪(因此使用本地版本的電梯 ),它工作正常。 所以模型沒有被解除分配,只是無效的參考不起作用。

編輯:崩潰報告

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)

我想這是一個錯誤。

如果您的Elevator類沒有從NSObject繼承,它可以工作。 否則會收到很長的錯誤消息。

class Elevator {

    var view: ViewController?
    var currentLevel = 1
    var newLevel: Int?
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM