2017-03-15 4 views
1

디버깅 기술을 향상시키고 자 노력 중이므로 here 주위에서 읽기 시작했습니다. 다음 코드 조각이 : 나는 각 줄에 중단 점을Xcode + LLDB : 'expression'을 사용하여 변수 값을 변경하려고합니다.

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

을, 나는 po label를 입력 할 때 이들 각각에 나는 내가 예상 얻을, 그래서

expression label = "jones" 
po label 

을 입력 결과는 jones이지만 레이블 및 콘솔에 표시된 텍스트 (print(label))는 tom입니다.

자습서 I 링크는 프로그램의 전체 실행에 변경 사항이 적용되어야한다고 말합니다. 거짓인가, 아니면 내가 잘못하고있는 것인가?

iPhone 7 Plus 시뮬레이터와 함께 Xcode 버전 8.2.1 (8C1002)을 사용하고 있습니다.

감사합니다.

+1

나는 swrap에 관해서 crapball을 모른다. 그러나 이것이 당신이하고있는 일이 objc라면 ... 작동하지 않을 것이다. 텍스트에 레이블을 할당 한 후에 같은 문자열에 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을 볼 수 있습니다. 컴파일러에서 문자열의 내용을 알 수 없게되면이 unboxing을 수행 할 수 없으며 디버거 변경 사항이 적용됩니다.

이 예제 코드를 사용 : 디버거에서

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 "컴파일러에서 문자열의 내용을 알 수 없게되면이 unboxing을 수행 할 수 없으며 디버거 변경 사항이 적용됩니다." 내가 제대로 이해하는지 잘 모르겠다. 'removeSubrange'와 같이 런타임 중에 struct 속성에 영향을주는 코드가 있다면 디버거의 변경 사항이 적용됩니다. 변화가 일어나는'Int'의 예는 무엇이겠습니까? 나는 곱셈과 같은 것으로 속성을 수정하려고 시도했지만,'expr'로부터의 변화는 여전히 일어나지 않습니다. – HuaTham

+0

잉크는 너무 간단해서이 문제를 해결하는 방법에 대한 좋은 제안이 없습니다. 일부 함수에 inout 매개 변수로 전달하면 트릭을 수행 할 수 있습니다. –

관련 문제