با عرض سلام و وقت بخیر خدمت کاربران سایت پی وی لرن . و کاربرانی که دوره کامل آموزش Swift را دنبال می کنند. توابع مدیریت حافظه در زبان Swift 4 از طریق شمارش معیارهای خودکار (ARC) مورد استفاده قرار می گیرند. ARC برای راه اندازی و غیر فعال کردن منابع سیستم استفاده می شود و بنابراین فضای حافظه مورد استفاده در نمونه های کلاس را زمانی که موارد دیگر مورد نیاز نیست، آزاد می کند. ARC اطلاعات مربوط به روابط بین نمونه های کد ما را مدیریت می کند تا منابع حافظه را به طور موثر مدیریت کند. در ادامه این مبحث به مرور مقدمه ای بر مفهوم ARC در Swift پرداخته ایم.
در این آموزش شما را با توابع و نمونه هایی از عملکرد مفهوم ARC در Swift آشنا خواهیم کرد.
ARC تکه ای از حافظه را برای ذخیره اطلاعات هر بار که یک کلاس جدیدتوسط () init ایجاد شود، اختصاص می دهد.
اطلاعات در مورد نوع نمونه و مقادیر آن در حافظه ذخیره می شود.
هنگامی که مثال کلاس دیگر مورد نیاز نیست، به طور خودکار حافظه را توسط () deinit برای ذخیره و بازیابی نمونه های کلاس بیشتر آزاد می کند.
ARC در حال پیگیری خصوصیات، ثابت ها و متغیرهایی است که در حال حاضر به آن اشاره دارد،و () deinit برای موراد بلااستفاده بکارم می رود.
ARC یک مرجع قدرتمند را برای ویژگی نمونه کلاس ها محدود می کند، ثابت ها و متغیرها برای محدود کردن عدم تخصیص زمانیکه نمونه کلاس ها در حال استفاده اند، بکار می روند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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) |
نتیجه ی کامپایل و اجرای مثال فوق :
1 2 | Swift 4 98 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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 |
نتیجه ی کامپایل و اجرای مثال فوق :
1 2 | Initializing: Swift 4 Initializing: ARC |
خصوصیات نوع کلاس دو راه برای حل سیکل های مرجع قوی دارند:
این مراجع برای فعال کردن یک نمونه برای مراجعه به موارد دیگر در یک چرخه مرجع استفاده می شوند.
سپس موارد ممکن است بجای مراقبت از چرخه مرجع قوی به هر نمونه مراجعه کنند.
هنگامی که کاربر می داند که برخی از نمونه ها ممکن است مقادیر “nil” را بازگردانند ممکن است که با استفاده از مراجع ضعیف اشاره کنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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 |
نتیجه ی کامپایل و اجرای مثال فوق :
1 2 | ARC Is The Main Module Sub Module with its topic number is 4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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 |
نتیجه ی کامپایل و اجرای مثال فوق :
1 2 | ARC Marks Obtained by the student is 98 |
هنگامی که ما یک معادله را به کلاس instance تعریف می کنیم بدنه closure می تواند یک سیکل مرجع نمونه خاص را بگیرند.
مرجع قوی برای closure توسط ‘self.someProperty’ یا ‘()’self.someMethod تعریف می شود.
سیکل های مرجع قوی برای انواع مرجع برای closure ها استفاده می شود.
مثال :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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()) |
نتیجه ی کامپایل و اجرای مثال فوق :
1 | <p>Welcome to Closure SRC</p> |
زمانیکه closure و instance به هر یک اشاره دارد. کاربر می تواند ضبط را در یک closure به عنوان یک مرجع بی نظیر تعریف کند.
پس از آن اجازه نمی دهد که کاربر در همان زمان نمونه را کنار بگذارد.
هنگامی که نمونه بعدها یک مقدار “nil” را به دست می گیرد، closure با نمونه ضعیف تعریف می شود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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 |
نتیجه ی کامپایل و اجرای مثال فوق :
1 2 | <Inside>ARC Weak References</Inside> Inside the deinit() |
توابع ARC در Swift برای راه اندازی و غیر فعال کردن منابع سیستم استفاده می شود، بنابراین فضای حافظه ای که استفاده می شود در مواقعی که بلا استفاده باشد آزاد می شود.