2016-08-25 10 views
1

Я только что последовал за учебником по ARC и был обеспечен этим кодом.ARC и как он работает точно.

Следующий класс ViewController и под ним класс Vehicle.

Что я получил от этого, так это то, что ARC по существу отслеживает экземпляр класса и выделяет для него часть памяти. Когда создаются «сильные» ссылки для экземпляра, arc увеличивает приращение количества ссылок на экземпляр. После того, как все они установлены на nil, ARC освобождает экземпляр из памяти. Инструктор также сказал что-то вроде того, как только все ссылки не используются, он освобождается из памяти. Я не совсем понял, в какой части они «не используются», поэтому я решил добавить кнопку, которая представляет собой другой контроллер View, который не содержит кода. Я подумал, что если я перейду к следующему контроллеру представления, deinit будет вызван как ссылка в контроллере 1, теперь не используются и, следовательно, освобождаются из памяти. Это было не так, и деинит не вызвал. Поэтому мне интересно, действительно ли ссылки остаются в памяти, если вы не установите их на ноль, всегда?

Часть 2 вопроса. Также, когда вы отвечаете на этот вопрос, у меня также есть другой вопрос, мне также интересно, применяет ли ARC только к экземплярам класса и ссылки на него, поскольку каждая часть документации или учебника, которые я смотрел кажется, только упоминание экземпляров класса. Например, если я установил var number = 2 var othernumber = number, «число» также сохраняется в памяти и освобождается, пока все ссылки на него не равны нулю. Если это так, то тот же вопрос применяется, устанавливает ли все ссылки равными нулю единственный способ освобождения от памяти? Извините за длинный вопрос, но я совершенно новый для концепции памяти.

import UIKit 

class ViewController: UIViewController { 


var ref1: Vehicle? 
var reference2: Vehicle? 
var ref3: Vehicle? 
var timer: NSTimer! 
var count = 0 
override func viewDidLoad() { 
    super.viewDidLoad() 

    ref1 = Vehicle(kind: "Car") 
    reference2 = ref1 
    ref3 = ref1 

    timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(tick), userInfo: nil, repeats: true) 


} 


func tick() { 
count++ 

    if count >= 3 { 
     ref3 = nil 
     reference2 = nil 



    } 

    if count == 5 { 
    ref1 = nil 


    } 


} 

}

class Vehicle { 

let type: String 


init(kind: String){ 
self.type = kind 
print("\(type) is being initialized") 
//when the class is instantiated, we get an initialization message. When class is deallocated, we get a deinit message. As in, all strong references are gone, we can deinitialize. 


} 
deinit { 
//class vehicle not in memory anymore as all strong references to it have been destroyed. This will be tested with segue as well. 
    print("\(type) is being deinitialized") 

}} 

ответ

3
  1. "использованное" терминология в заблуждение/вводящие в заблуждение (или, в лучшем случае, неточными). С ARC объект не будет выпущен, пока не останется никаких сильных ссылок, простых и простых. Если вы nil, все эти сильные ссылки или те сильные ссылки выпадают из области действия, то есть когда объект освобождается.

    Между прочим, имейте в виду, что scheduledTimerWithTimeInterval устанавливает свою собственную сильную ссылку на свою цель. У вас есть invalidate таймер, чтобы решить эту сильную ссылку.

  2. ARC применяется только к ссылочным типам (то есть class экземпляров). Он просто не применяется к типам значений (например, числовым типам или типам struct).

    Итак, рассмотрим

    var number = 2 
    var othernumber = number 
    

    othernumber не ссылается на number. Он делает копию. Это новый объект, значение которого имеет то же значение, что и number. Для обсуждения дифференцирования типов значений Swift из ссылочных типов см. WWDC 2015 Building Better Apps with Value Types. (Кстати, за кулисами управление памятью сложных типов значений на самом деле сложнее, чем для простых типов значений, но это не очень актуально в этом разговоре. Но это обсуждается в деталях в видео, если вы заинтересованные.)

+0

спасибо за очистку этого Rob, хотя в каком сценарии сильная ссылка выпадет «вне сферы действия» – slimboy

+0

Так же, я угадываю типы значений, они также выделяются в память и освобождаются. Должен ли программист самостоятельно освобождать их, чтобы сохранить пространство памяти? – slimboy

+0

Спасибо, что поняли, что я понял. – slimboy

1

Это большой вопрос.

Для того, чтобы понять ARC, вам действительно нужно понять ручной подсчет ссылок.

Подсчет ссылок - это способ отслеживания того, какие объекты все еще используются, и которые могут быть освобождены.

В ручном подсчете ссылок объекты имеют счетчик удержания.

Вы отправляете сообщение сохранения объекту, чтобы увеличить его количество удержания, и отпустите, чтобы уменьшить его количество удержаний. Если отправка сообщения освобождения объекту приводит к тому, что счетчик удержания сохраняется до 0, объект освобождается/освобождается.

Существует также сообщение autorelease, которое добавляет объект в «пул автообновлений». Каждый раз, когда ваш код возвращается и цикл события посещается, все объекты в пуле авторесурсов получают отправленное сообщение о выпуске за каждый раз, когда они находятся в пуле автозапуска. (Вы можете отправить нескольким сообщениям об автоопределении объекту, но не обращайте на них внимания.) Autorelease полезно для возврата временных объектов, которые уходят, если вы не делаете ничего особенного с ними. Автореализованный объект застревает во время текущей цепочки вызовов, но освобождается, когда ваш код возвращается, если никто его не сохранил.

Объекты создаются и возвращаются владельцу с номером ссылки 1, и владелец несет ответственность за отправку сообщения о выпуске объекта, когда он сделан с ним.

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

ARC использует все перечисленные выше механизмы, но компилятор анализирует ваш код и вставляет в него сохраненные, освобождающие и автоответчики. Он также удаляет лишние звонки с сохранением/освобождением до минимального необходимого минимума.

В ARC вам просто нужно объявить переменные сильными или слабыми, а компилятор сделает все остальное. Есть еще несколько исправлений, но по большей части вам не нужно беспокоиться об управлении памятью.

Сохранение объекта в сильной переменной заставляет компилятор генерировать вызов сохранения. Обнуление сильной переменной заставляет компилятор отправлять сообщение о выпуске.

В отличие от сбора мусора, системе не нужно останавливаться и выполнять длительную очистку по памяти. Объекты освобождаются, как только нет более сильных ссылок на них.