Swift - Tổng quan về ARC

Các chức năng quản lý bộ nhớ và việc sử dụng nó được xử lý bằng ngôn ngữ Swift 4 thông qua Đếm tham chiếu tự động (ARC). ARC được sử dụng để khởi tạo và khởi tạo tài nguyên hệ thống do đó giải phóng không gian bộ nhớ được sử dụng bởi các cá thể lớp khi các cá thể không còn cần thiết nữa. ARC theo dõi thông tin về mối quan hệ giữa các trường hợp mã của chúng tôi để quản lý tài nguyên bộ nhớ một cách hiệu quả.

Chức năng của ARC

  • ARC cấp phát một phần bộ nhớ để lưu trữ thông tin mỗi khi một cá thể lớp mới được tạo bởi init ().

  • Thông tin về kiểu thể hiện và các giá trị của nó được lưu trong bộ nhớ.

  • Khi cá thể lớp không còn cần thiết nữa, nó sẽ tự động giải phóng không gian bộ nhớ bằng deinit () để lưu trữ và truy xuất cá thể lớp khác.

  • ARC theo dõi các thuộc tính, hằng số và biến của các cá thể lớp hiện đang tham chiếu để deinit () chỉ được áp dụng cho các cá thể không sử dụng đó.

  • ARC duy trì một 'tham chiếu mạnh' đến các thuộc tính, hằng số và biến thể hiện của lớp đó để hạn chế việc phân bổ khi cá thể lớp hiện đang được sử dụng.

Chương trình 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)

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

Swift 4
98

Phiên bản lớp chu kỳ tham chiếu mạnh mẽ của ARC

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

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

Initializing: Swift 4
Initializing: ARC

Tài liệu tham khảo yếu và chưa được biết đến của ARC

Thuộc tính kiểu lớp có hai cách để giải quyết các chu trình tham chiếu mạnh:

  • Tài liệu tham khảo yếu
  • Tài liệu tham khảo chưa biết

Các tham chiếu này được sử dụng để cho phép một cá thể tham chiếu đến các cá thể khác trong một chu kỳ tham chiếu. Sau đó, các cá thể có thể tham chiếu đến từng và mọi trường hợp thay vì quan tâm đến chu trình tham chiếu mạnh. Khi người dùng biết rằng một số phiên bản có thể trả về giá trị 'nil', chúng tôi có thể chỉ ra rằng sử dụng tham chiếu yếu. Khi instance sẽ trả về một cái gì đó thay vì nil thì hãy khai báo nó với tham chiếu không xác định.

Chương trình tham chiếu yếu

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

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

ARC Is The Main Module
Sub Module with its topic number is 4

Chương trình tham khảo chưa biết

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

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

ARC
Marks Obtained by the student is 98

Các chu trình tham chiếu mạnh mẽ để đóng cửa

Khi chúng ta gán một bao đóng cho thuộc tính cá thể lớp và cho phần thân của bao đóng để nắm bắt chu trình tham chiếu mạnh của cá thể cụ thể có thể xảy ra. Tham chiếu mạnh mẽ đến bao đóng được định nghĩa bởi 'self.someProperty' hoặc 'self.someMethod ()'. Các chu kỳ tham chiếu mạnh được sử dụng làm loại tham chiếu cho các lần đóng cửa.

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())

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

<p>Welcome to Closure SRC</p>

Tài liệu tham khảo yếu và chưa được biết đến

Khi bao đóng và cá thể tham chiếu đến nhau, người dùng có thể xác định việc nắm bắt trong một bao đóng là một tham chiếu không xác định. Sau đó, nó sẽ không cho phép người dùng phân bổ cá thể cùng một lúc. Khi cá thể một lúc nào đó trả về giá trị 'nil' xác định việc đóng với cá thể yếu.

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

Khi chúng tôi chạy chương trình trên bằng sân chơi, chúng tôi nhận được kết quả sau:

<Inside>ARC Weak References</Inside>
Inside the deinit()