2017-11-07 11 views
1

私は、XcodeやLLDBのドキュメントを読んでもわからないようなことに遭遇しました。アプリケーションがブレークポイントを持つ行に到達すると、ブレークポイントが存在する場合は、LLDBがその行でブレークするはずです。突然変異関数を実行している間にその行のコードにアクセスしても、ブレークポイントはトリガーされません。Xcodeでブレークポイントをトリガするメンバーを変更していないのはなぜですか?

は、次の例を考えてみましょう:

class DataSource { 

    private init(){ 

     data = [] 

     for i in 0..<10 { 

      data.append(i) // mutating func 
     } 
    } 

    static let sharedInstance = DataSource() 

    var data: [Int]! // Set a breakpoint on this line 
} 

class Worker { 

    func work(){ 

     print("Append item") 

     DataSource.sharedInstance.data.append(23) // mutating func 

     print("Get first item") 

     print(DataSource.sharedInstance.data[0]) // subscript - TRIGGERS BREAKPOINT 

     print("Drop first") 

     print(DataSource.sharedInstance.data.dropFirst()) // func - TRIGGERS BREAKPOINT 

     print("Remove first") 

     print(DataSource.sharedInstance.data.removeFirst()) // mutating func 

     print("Remove at 0") 

     print(DataSource.sharedInstance.data.remove(at: 0)) // mutating func 
    } 
} 

.data[0].dropFirst()は、ブレークポイントをトリガされ、他の関数呼び出しではありません。私が見ることができる唯一の違いは、破損​​していないそれらの機能がmutatingの機能であるということです。

ブレークポイントはトリガされませんが、同じ行に追加されたウォッチポイントが毎回トリガされます。

誰かがこの現象を説明できますか? MacOSで

答えて

0

、あなたのブレークポイントはに解決:理にかなっていること

(lldb) break list 
Current breakpoints: 
1: source regex = "Set a breakpoint", exact_match = 0, locations = 3, resolved = 3, hit count = 3 
    1.1: where = mutable`mutable.DataSource.(in _788A7EC739C0395377AC3966BEDD9D35).init() -> mutable.DataSource + 40 at mutable.swift:15, address = 0x0000000100001b08, resolved, hit count = 1 
    1.2: where = mutable`mutable.DataSource.data.getter : Swift.ImplicitlyUnwrappedOptional<Swift.Array<Swift.Int>> + 80 at mutable.swift:15, address = 0x0000000100001e00, resolved, hit count = 2 
    1.3: where = mutable`mutable.DataSource.data.setter : Swift.ImplicitlyUnwrappedOptional<Swift.Array<Swift.Int>> + 96 at mutable.swift:15, address = 0x0000000100001e70, resolved, hit count = 0 

、「データ」IVARの定義は、セッター、ゲッターとinitメソッドを生成し、それらの機能は、この行に関連付けられます。

しかし、あなたは、例えば可変アクセスのためのコード、アペンドコールを見れば、これらの方法のいずれもが使用されていないように、代わりにアセンブリが見えます:それはアクセスするタイプのメタデータを通過している

(lldb) dis -c 5 -s 0x10000203b 
mutable`Worker.work(): 
    0x10000203b <+235>: callq 0x100002cf0    ; type metadata accessor for mutable.DataSource at mutable.swift 
    0x100002040 <+240>: movq %rax, -0xf0(%rbp) 
    0x100002047 <+247>: callq 0x100001d50    ; mutable.DataSource.sharedInstance.unsafeMutableAddressor : mutable.DataSource at mutable.swift 
    0x10000204c <+252>: movq (%rax), %rax 
    0x10000204f <+255>: movq %rax, %rcx 

変数を変更しようとしています。これは汎用関数であり、 "data" ivarの定義によってトリガーされないため、その定義行に割り当てられません。そのアクセスは、ゲッターやセッターをスキップできることを知っている必要がありますが、それがなぜそれを説明する他の誰かを取得する必要があります...

あなたはこれについて不思議であればSwiftはデータへのアクセスを可能にし、言語の実装に精通した人が重いかもしれません。

関連する問題