2017-10-11 1 views
2

이 코드는 CFAttributedString이 스레드로부터 안전하지 않다는 것을 보여 줍니까? 아니면 설정에 문제가 있습니까?CFAttributedString 스레드 안전성

CFAttributedString이 여러 스레드에서 읽는 것이 안전하다고 생각했지만 몇 번 실행될 때마다이 코드에서 충돌이 발생합니다.

@IBAction func testIt(_ sender: Any?) { 
    let testString = "Hello world! Lets make this a bit longerrrrrrrrrrrrrrrr." as CFString 
    let testStringLength = CFStringGetLength(testString) 

    let testAttributedString = CFAttributedStringCreateMutable(kCFAllocatorDefault, testStringLength) 
    CFAttributedStringReplaceString(testAttributedString, CFRange(location: 0, length: 0), testString) 
    CFAttributedStringEndEditing(testAttributedString) 
    for i in 0..<testStringLength { 
     let range = CFRange(location: i, length: 1) 
     let keyAndValue = "\(i)" as CFString 
     CFAttributedStringSetAttribute(testAttributedString, range, keyAndValue, keyAndValue) 
    } 

    let immutableTestAttributedString = CFAttributedStringCreateCopy(kCFAllocatorDefault, testAttributedString) 
    DispatchQueue.concurrentPerform(iterations: 100) { _ in 
     var index: CFIndex = 0 
     var effectiveRange: CFRange = CFRange(location: 0, length: 0) 
     while index < testStringLength { 
      // Crash happens here EXC_BAD_ACCESS (code=1, address=0x24) 
      let _ = CFAttributedStringGetAttributes(immutableTestAttributedString, index, &effectiveRange) 
      index = effectiveRange.location + effectiveRange.length 
     } 
    } 
} 

답변

1
let testString = "Hello world! Lets make this a bit longerrrrrrrrrrrrrrrr." as CFString 

이 간접 약 2 층이며, 당신과 사이가 여전히 작동하는지 여부 (내장이 아래로 매우 다른 코드 경로를 호출 여부를 CFString,로 가장 신속 문자열 a radar).

CFString을 올바르게 작성하고 예상대로 작동하는지 확인해보십시오.

var bytes = Array("Hello world! Lets make this a bit longerrrrrrrrrrrrrrrr.".utf16) 
let testString = CFStringCreateWithCharacters(nil, &bytes, bytes.count) 

(물론 내가보기 엔 NSAttributedString보다는 CFAttributedString이 모든 일을 권장합니다. Swift-> 재단 브리징이 훨씬 간단하고> 재단 -> CoreFoundation에서 브리징 (가) Swift-.이 월에 비해 지속적으로 사용된다 그냥 브리지에서 버그가 수 있지만, 당신의 세계는 여전히 당신이 그것을 피할 수 있다면 훨씬 더 쉽게 될 것입니다.)


나는 순수한 CFString 승/문제를 재현 할 수 없었던 반면,이 확실히 스레드 안전하지 않습니다. CoreFoundation은 오픈 소스이며 (일종의 ...)이 코드는 사용자가 직접 볼 수 있습니다. 결국 CFAttributedStringGetAttributesblockForLocation으로 전화를 걸면 내부 캐시가 업데이트되고 주변 캐시는 잠겨 있지 않습니다. 나는 스레드 안전하다고 약속 한 문서에서 아무것도 보지 못했다.

+0

팁을 보내 주셔서 감사합니다. 불행히도 그 방법으로 문자열을 만들면 같은 위치에 오류가 표시됩니다. 이 경우 CFAttributedString을 사용하는 이유는 코드가 뜨거워서 CFAttributedStringSetAttribute가 훨씬 빠르게 실행되어 NSMutableAttributedString 속성을 추가하는 것 때문입니다. –

+0

신속한 브리징이 작동하는 방법에 대해 더 자세히 알 수있는 지침이 있습니까? 특히 성능 문제는주의해야합니다. Swift의 Core Text로 많은 작업을하고 있으며 현재 최적화 단계에 있습니다. 감사. –

+0

감사합니다. 도움을 받으십시오. NSAttributedString이 안전하고 Core Foundation이 "일반적으로"안전하다고 여기기 때문에 스레드 안전을 기대하고있었습니다. https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html 그러나이 경우 NOT, 매우 잘 알고 당신의 도움에 다시 한번 감사드립니다. –