2017-01-20 2 views
1

Я делал некоторые тесты с указателями в Swift и хотел проверить, что объекты, которые я принимал указатели, не сохранялись.Почему Swift «Managed.fromOpaque.takeUnretainedValue()« сохраняет значение?

func test1(){ 
    let str = aaa(); 
    print(CFGetRetainCount(str)) 
    let ptr1 = Unmanaged.passUnretained(str).toOpaque() 
    print(CFGetRetainCount(str)) 
    let str2 = Unmanaged<aaa>.fromOpaque(ptr1).takeUnretainedValue(); 
    print(CFGetRetainCount(str2)) 
} 

В результате получается 2,2,3. Поэтому «passUnretained» не сохранялся, но «takeUnretainedValue» сделал.

Изменение на «takeRetainedValue» устраняет проблему и вызывает ожидаемый сбой. Выход 2,2,2.

func test1(){ 
    let str = aaa(); 
    print(CFGetRetainCount(str)) 
    let ptr1 = Unmanaged.passUnretained(str).toOpaque() 
    print(CFGetRetainCount(str)) 
    let str2 = Unmanaged<aaa>.fromOpaque(ptr1).takeRetainedValue(); 
    print(CFGetRetainCount(str2)) 
} 

Итак, в заключение, «takeRetainedValue» НЕ сохраняет значение.

Обновление: Я отредактировал этот вопрос, чтобы удалить некоторые ранее запутанные утверждения и вернул его в основной вопрос программирования.

+0

Да. Я понял первоначальный вопрос. «passUnretained» не сохраняется, но «takeUnretainedValue» делает. Но это не связанные пары, но passUnretained (+0) противопоставляется passRetained (+1). Как вы думаете, я должен просто удалить эту проблему, поскольку нет никакого обоснования или нет проблемы с кодированием? – user1122069

+0

Я рад, что это имеет смысл для вас. Не саркастично. Важно понимать, что означают термины, чтобы правильно использовать их и иметь возможность просматривать код. – user1122069

ответ

0

На самом деле, оказывается, что «takeUnretainedValue» не сохраняет значение, скорее это выполняется самим присваиванием после возвращения значения.

Я тестировал и обнаружил, что до тех пор, пока «passRetained» используется с «takeRetained» и «passUnretained» с «takeUnretained», тогда переменная не течет, и это просто +1 из-за добавленной новой переменной.

func test1() -> UnsafeMutableRawPointer { 
    let str = aaa(); 
    print(CFGetRetainCount(str)) 
    let ptr1 = Unmanaged.passRetained(str).toOpaque() 
    print(CFGetRetainCount(str)) 
    let str2 = Unmanaged<aaa>.fromOpaque(ptr1).takeRetainedValue(); 
    print(CFGetRetainCount(str2)) 
    print(str2); 
    print("111"); 
    print(str.b) 
    return ptr1; 
} 

let ptr4 = test1(); 
let str4 = Unmanaged<aaa>.fromOpaque(ptr4).takeUnretainedValue(); 
print(CFGetRetainCount(str4)) 
print(str4.b); 

Вот тест, показывающий, что takeUnretainedValue не увеличивает количество реф (удалено назначение, но называется функцией так или иначе).

func test1() { 
    let str = aaa(); 
    print(CFGetRetainCount(str)) 
    let ptr1 = Unmanaged.passUnretained(str).toOpaque() 
    print(CFGetRetainCount(str)) 
    Unmanaged<aaa>.fromOpaque(ptr1).takeUnretainedValue(); 
    print(CFGetRetainCount(str)) 
    //print(str2); 
    print("111"); 
    print(str.b) 
} 

Аналогичные тесты показывают, что «takeRetainedValue» уменьшает количество удержаний. Это относится к «лишнему удержанию» от passRetained и возвращает значение, как оно было, когда оно начиналось. Затем также присваивается значение +1.

+0

Вопрос в том, что «Почему Swift» Managed.fromOpaque.takeUnretainedValue() «сохраняет значение?». Дело в том, что takeUnretainedValue не сохраняет и, следовательно, путаницу. – user1122069

Смежные вопросы