Swift - Обзор ARC
Функции управления памятью и ее использование обрабатываются на языке Swift 4 с помощью автоматического подсчета ссылок (ARC). ARC используется для инициализации и деинициализации системных ресурсов, освобождая тем самым пространства памяти, используемые экземплярами класса, когда они больше не нужны. ARC отслеживает информацию об отношениях между нашими экземплярами кода для эффективного управления ресурсами памяти.
Функции ARC
ARC выделяет часть памяти для хранения информации каждый раз, когда новый экземпляр класса создается с помощью init ().
Информация о типе экземпляра и его значениях хранится в памяти.
Когда экземпляр класса больше не нужен, функция deinit () автоматически освобождает пространство памяти для дальнейшего хранения и извлечения экземпляра класса.
ARC отслеживает свойства, константы и переменные экземпляров класса, на которые в настоящее время ссылаются, так что deinit () применяется только к этим неиспользуемым экземплярам.
ARC поддерживает «строгую ссылку» на эти свойства экземпляра класса, константы и переменные, чтобы ограничить освобождение, когда экземпляр класса в настоящее время используется.
Программа ARC
class StudDetails {
var stname: String!
var mark: Int!
init(stname: String, mark: Int) {
self.stname = stname
self.mark = mark
}
deinit {
print("Deinitialized \(self.stname)")
print("Deinitialized \(self.mark)")
}
}
let stname = "Swift 4"
let mark = 98
print(stname)
print(mark)
Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -
Swift 4
98
Экземпляры классов ARC Strong Reference Cycles
class studmarks {
let name: String
var stud: student?
init (name: String) {
print("Initializing: \(name)")
self.name = name
}
deinit {
print("Deallocating: \(self.name)")
}
}
class student {
let name: String
var strname: studmarks?
init (name: String) {
print("Initializing: \(name)")
self.name = name
}
deinit {
print("Deallocating: \(self.name)")
}
}
var shiba: studmarks?
var mari: student?
shiba = studmarks(name: "Swift 4")
mari = student(name: "ARC")
shiba!.stud = mari
mari!.strname = shiba
Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -
Initializing: Swift 4
Initializing: ARC
Слабые и бесхозные ссылки ARC
Свойства типа класса имеют два способа разрешить циклы сильных ссылок:
- Слабые ссылки
- Необоснованные ссылки
Эти ссылки используются для того, чтобы один экземпляр мог ссылаться на другие экземпляры в цикле ссылок. Тогда экземпляры могут ссылаться на каждый экземпляр вместо того, чтобы заботиться о цикле сильных ссылок. Когда пользователь знает, что какой-то экземпляр может возвращать нулевые значения, мы можем указать это, используя слабую ссылку. Когда экземпляр собирается вернуть что-то, а не nil, объявляйте это с помощью ссылки unowned.
Слабая справочная программа
class module {
let name: String
init(name: String) { self.name = name }
var sub: submodule?
deinit { print("\(name) Is The Main Module") }
}
class submodule {
let number: Int
init(number: Int) { self.number = number }
weak var topic: module?
deinit { print("Sub Module with its topic number is \(number)") }
}
var toc: module?
var list: submodule?
toc = module(name: "ARC")
list = submodule(number: 4)
toc!.sub = list
list!.topic = toc
toc = nil
list = nil
Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -
ARC Is The Main Module
Sub Module with its topic number is 4
Неофициальная справочная программа
class student {
let name: String
var section: marks?
init(name: String) {
self.name = name
}
deinit { print("\(name)") }
}
class marks {
let marks: Int
unowned let stname: student
init(marks: Int, stname: student) {
self.marks = marks
self.stname = stname
}
deinit { print("Marks Obtained by the student is \(marks)") }
}
var module: student?
module = student(name: "ARC")
module!.section = marks(marks: 98, stname: module!)
module = nil
Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -
ARC
Marks Obtained by the student is 98
Циклы сильных ссылок для замыканий
Когда мы назначаем замыкание свойству экземпляра класса и телу замыкания для захвата конкретного экземпляра, может возникнуть цикл сильных ссылок. Сильная ссылка на закрытие определяется с помощью self.someProperty или self.someMethod (). Циклы строгих ссылок используются в качестве типов ссылок для замыканий.
class HTMLElement {
let samplename: String
let text: String?
lazy var asHTML: () -> String = {
if let text = self.text {
return "<\(self.samplename)>\(text)</\(self.samplename)>"
} else {
return "<\(self.samplename) />"
}
}
init(samplename: String, text: String? = nil) {
self.samplename = samplename
self.text = text
}
deinit {
print("\(samplename) is being deinitialized")
}
}
var paragraph: HTMLElement? = HTMLElement(samplename: "p", text: "Welcome to Closure SRC")
print(paragraph!.asHTML())
Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -
<p>Welcome to Closure SRC</p>
Слабые и бесхозные ссылки
Когда замыкание и экземпляр ссылаются друг на друга, пользователь может определить захват в замыкании как не принадлежащую ему ссылку. Тогда это не позволит пользователю освободить экземпляр одновременно. Когда экземпляр когда-нибудь возвращает значение 'nil', определите закрытие с помощью слабого экземпляра.
class HTMLElement {
let module: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in
if let text = self.text {
return "<\(self.module)>\(text)</\(self.module)>"
} else {
return "<\(self.module) />"
}
}
init(module: String, text: String? = nil) {
self.module = module
self.text = text
}
deinit {
print("\(module) the deinit()")
}
}
var paragraph: HTMLElement? = HTMLElement(module: "Inside", text: "ARC Weak References")
print(paragraph!.asHTML())
paragraph = nil
Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -
<Inside>ARC Weak References</Inside>
Inside the deinit()