2017-03-15 54 views
1

デバッグのスキルを向上させようとしていますので、hereを読んで始めました。私はラインのそれぞれにブレークポイントを持ち、それらのそれぞれに、私はそうXcode + LLDB: 'expression'を使用して変数値を変更しようとしています

expression label = "jones" 
po label 

を入力し、私はpo labelを入力すると、私は期待を取得

var label = "tom" 
self.label.text = label 
print(label) 

:私は、次のコードを持っています結果はjonesですが、ラベルとコンソールに表示されるテキスト(print(label))はtomです。

このチュートリアルIリンクには、変更がプログラムの実行全体に反映されることが記載されています。それは間違っているのですか?何か間違っていますか?

私はiPhone 7 PlusシミュレータでXcodeバージョン8.2.1(8C1002)を使用しています。

ありがとうございます!

+1

私はswiftについてのcrapballを知らないが、これがあなたがしていたことがうまくいかない場合...テキストにラベルを割り当てた後、同じ文字列へのポインタが2つになり、古いラベルでは、self.label.textが何を指しているかは変わりません... KVOが起こっていない限り... 'po self.label.text =" jones "'は何をしますか? –

+0

もちろん、stringは構造体ですが、私は 'label'によって指された新しいものを作成していましたが、self.label.textはまだ古いものを指していました。ブリリアント! :) – Yotam

答えて

1

私はこれが役立つとは確信していませんが、何が起こっているかは、あなたが考えるより少し複雑です。

スウィフト文字列は実際には構造体なので、self.text.labelに代入する前に行を停止し、label varに新しい値を代入すると、実際に構造体の内容が変更されます。その構造体からself.text.labelに割り当てると、実際には新しい値が取り出されるはずです...

この構造体をアンボックスすることは、不必要にならないようにすばやくコンパイラがスマートです可能であれば逆参照。これは-Ononeでも発生します。

たとえば、あなたの例では、即座にコンパイルされたコードでは、文字列とその内容を直接参照するコードがアンボックスされています。実際の文字列の内容を変更しても、すでに割り当てコード内のボックス化されていない内容への参照は変更されないので、変更は反映されません。

このIRLを見ることができます。コンパイラで文字列の内容を知ることができない場合、このボックスを解除することはできず、デバッガの変更が反映されます。この例のコード使用

:デバッガで

class HasLabel 
{ 
    var label : String = "Default Value" 
} 

func 
main() 
{ 
    var myLabel = HasLabel() 
    var string = "set in code" 

    string.removeSubrange(string.startIndex..<string.endIndex) 
    string.append("Different string in code") 
    myLabel.label = string // Set a breakpoint here 
    print ("Did it change? string: \"\(string)\" Label: \"\(myLabel.label)\"") 
} 

main() 

は、私は以下を参照してくださいあり

(lldb) br s -p "Set a breakpoint here" 
Breakpoint 1: where = tryme`tryme.main() ->() + 499 at tryme.swift:14, address = 0x0000000100001e93 
(lldb) run 
Process 8323 launched: '/private/tmp/tryme' (x86_64) 
Process 8323 stopped 
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 
    frame #0: 0x0000000100001e93 tryme`tryme.main() ->() at tryme.swift:14 
    11 
    12  string.removeSubrange(string.startIndex..<string.endIndex) 
    13  string.append("Different string in code") 
-> 14  myLabel.label = string // Set a breakpoint here 
     ^
    15  print ("Did it change? string: \"\(string)\" Label: \"\(myLabel.label)\"") 
    16 } 
    17 
(lldb) expr string = "Set in debugger" 
(lldb) c 
Process 8323 resuming 
Did it change? string: "Set in debugger" Label: "Set in debugger" 
Process 8323 exited with status = 0 (0x00000000) 

デバッガの変更は、実際にかかった参照してください。しかし、string.removeSubrangestring.appendをコメントアウトすると、変更はもう行われなくなります。

+0

非常に便利な、多くのありがとう! – Yotam

+0

@Jim "コンパイラで文字列の内容がわからない場合、このアンボックスを実行できず、デバッガの変更が反映されます。私が正しく理解しているかわかりません。 'removeSubrange'のように、実行時に構造体プロパティに影響を与えるコードがある限り、デバッガの変更が有効になると言っていますか?変更が行われるIntの例は何でしょうか?私は乗算のようなものでプロパティを修正しようとしましたが、 'expr'からの変更はまだ行われません。 – HuaTham

+0

私はこれを回避するための良い提案はありません。いくつかの関数にinoutパラメータとして渡すことは、このトリックを行うかもしれません。 –

関連する問題