Skip to main content

Cơ chế quản lý bộ nhớ trong iOS - ARC và MRC


Chào cả nhà hôm nay mình sẽ viết về 2 cơ chế quản lý bộ nhớ trong ios đó là ARC và MRC. Mặc dù có một số thuật ngữ tiếng anh nhưng mình nghĩ các bạn khi đọc và đã có kiến thức về bộ nhớ heap và stack rồi thì sẽ không là vấn đề. Link tham khảo: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID48

ARC

ARC được viết tắt bởi Automatic Reference Counting: Cơ chế tự động đếm số lượng reference ARC để theo dõi và quản lý bộ nhớ app được sử dụng. Nó tự động giải phóng bộ nhớ không dùng đến nữa.Reference counting chỉ áp dụng cho instances of class. Struct và enum là value type nên sẽ không stored và passed by referance.

How to ARC work

Mỗi lần mà bạn tạo 1 instance mới của một class, ARC cấp phát một vùng nhớ để lưu trữ thông tin về cái instance đó. Vùng nhớ đó nó sẽ giữ thông tin về loại của instance cùng với bất kì những biến lưu trữ với instance đó. Khi mà instance đó không cần dùng đến nữa, ARC sẽ tự động giải phóng bộ nhớ được sử dụng bởi instance đó vì thế vùng nhớ được giải phóng có thể cho những mục đích khác. Điều này đảm bảo rằng class instance không chiếm dụng vùng nhớ khi nó không làm cần dùng đến nữa. Tuy nhiên nếu ARC đã deallocated một instance mà nó vẫn được sử dụng, nó sẽ không còn có thể truy cập vào instance của properties hoặc instance của methods. Vì vậy nếu mình còn cố gắng truy cập vào chúng thì app sẽ bị crash đó. Nhưng bạn hãy yên tâm về vấn đề mà 1 instance không tự dưng biến mất đột ngột trong khi nó đang được "xài" thì có biện pháp để khắc phục là ARC sẽ theo dõi có bao nhiêu properties, constants, và variable hiện tại đang referring tới class instance đó. ARC sẽ không deallocated một instance ngay khi vẫn còn 1 strong referance. Đến đây sẽ có 1 định nghĩa mới là strong referance. Như vậy strong referance là gì?

Strong reference là gì?

Đó chính là hiện tượng khi 2 class có referance tới nhau và khi giải phóng class instance thì một trong 2 instance vẫn còn tồn tại. Cách giải quyết đó là xác định mối quan hệ giữa các class là weak hay unowned. Còn nếu không deallocated thì sẽ xảy ra hiện tượng memory leak.

Resolving strong reference cycle

Có 2 hướng để giải quyết khi làm việc với properties: weak và unowned Weak: được dùng khi instance khác có vòng đời ngắn hơn tức là cái instance đó deallocate trước và nó có thể nil. Unowned: same life-time hoặc có longer life-time và không thể nil.

Strong reference cycles cho closures:

Khi assign 1 closure tới 1 properties của 1 class instance và trong body của closure capture instance bằng cách self.properties hoặc self.method thì sẽ dẫn tới hiện tượng strong referance cycles Cách giải quyết cho closures : thêm vào trong capture list [weak self , unowed delegate = self.delegate ]... tuỳ vào trường hợp.

MRC

MRC được viết tắt của Menual memory management: tự quản lý mọi hoạt động của đối tượng. Thành lập 1 ownership đến đối tượng để sử dụng nó và remote nó đi khi không sử dụng nó nữa, một cách hoàn toàn thủ công. Apple cung cấp một số method để thực hiện điều này Alloc : khởi tạo 1 đối tượng và yêu cầu quyền sở hữu đối tượng đó Retain: Tăng retain count của đối tượng lên 1, gửi giữ 1 ownership đến 1 đối tượng đã tồn tại Copy: Copy một đối tượng ra một một vùng mới và giữ một ownership đến nó Release: Giảm retain count của đối tượng đi 1 Autorelease: Giảm đối tương đi 1 nhưng không lập tức

Có hai vấn đề thường xảy ra trong quá trình quản lý một đối tượng một cách manual

  1. Khi dùng xong một đối tượng mà quên không release nó đi thì sẽ dẫn đến là nó sẽ không được giải phóng trong bộ nhớ, dẫn đến rò rỉ bộ nhớ, memory leak. Bình thường vấn đề này cũng không lớn, nó chỉ trở nên nghiêm trọng khi chúng ta dùng hết bộ nhớ, chương trình sẽ bị crash.
  2. Khi chúng ta release một đối tượng quá nhiều lần cũng sẽ dẫn đến tình trạng dangling pointer. Một con trỏ không tồn tại và khi nó đã không tồn tại mà chúng ta cố gắng truy cập đến nó thì tất nhiên sẽ crash app.
Trên đây mình có tổng quát hoá về 2 cơ chế quản lý bộ nhớ trong ios. Cảm ơn các bạn đã đọc và mọi câu hỏi hay ý kiến các bạn hãy để dưới bình luận nhé

Comments

Popular posts from this blog

Swift Tool Belt, Part 1: Adding a Border, Corner Radius, and Shadow to a UIView with Interface Builder

During my iOS work, I’ve assembled a set of code that I bring with me on every iOS project. I’m not talking about large frameworks or CocoaPods here. These are smaller Swift extensions or control overrides that are applicable to many projects. I think of them as my tool belt. In this post, I’ll show you an extension that will add a border, a corner radius, and a shadow to any UIView, UIButton, or UILabel and allow you to preview what it will look like in Interface Builder. Back in 2014, I wrote a blog post on Expanding User-Defined Runtime Attributes in Xcode where I added a border, corner radius, and shadow to a UIView using Interface Builder’s user-defined runtime attributes. This solution had no type checking—you had to type the property you wanted to modify by hand and often had to look up what it was called. You also had to run your project in order to see the effect of the runtime attribute. Starting with Xcode 6 , there is a new mech...

Alamofire vs URLSession

Alamofire vs URLSession: a comparison for networking in Swift Alamofire and URLSession both help you to make network requests in Swift. The URLSession API is part of the foundation framework, whereas Alamofire needs to be added as an external dependency. Many  developers  doubt  whether it’s needed to include an extra dependency on something basic like networking in Swift. In the end, it’s perfectly doable to implement a networking layer with the great URLSession API’s which are available nowadays. This blog post is here to compare both frameworks and to find out when to add Alamofire as an external dependency. Build better iOS apps faster Looking for a great mobile CI/CD solution that has tons of iOS-specific tools, smooth code signing, and even real device testing? Learn more about Bitrise’s iOS specific solutions! This shows the real power of Alamofire as the framework makes a lot of things easier. What is Alamofire? Where URLSession...

Frame vs Bounds in iOS

This article is a repost of an answer I wrote on Stack Overflow . Short description frame = a view’s location and size using the parent view’s coordinate system ( important for placing the view in the parent) bounds = a view’s location and size using its own coordinate system (important for placing the view’s content or subviews within itself) Details To help me remember frame , I think of a picture frame on a wall . The picture frame is like the border of a view. I can hang the picture anywhere I want on the wall. In the same way, I can put a view anywhere I want inside a parent view (also called a superview). The parent view is like the wall. The origin of the coordinate system in iOS is the top left. We can put our view at the origin of the superview by setting the view frame’s x-y coordinates to (0, 0), which is like hanging our picture in the very top left corner of the wall. To move it right, increase x, to move it down increase y. To help me remember bound...