Phần 5: “Vật lộn” với việc quản lý bộ nhớ trong Objective-C | Lập Trình TV

ICTSharing

Chào mừng bạn đến với bài 5 của loạt bài về Objective-C này. Trong bài này, chúng ta sẽ tìm hiểu việc quản lý bộ nhớ, một một phần rất quan trọng của Objective-C (và nhiều ngôn ngữ khác). Hầu hết các ngôn ngữ kịch bản (chẳng hạn như PHP) quản lý bộ nhớ một cách tự động, nhưng Objective-C đòi hỏi rằng chúng ta là cẩn thận với việc sử dụng bộ nhớ của chúng ta. Điều đó có nghĩa là ta phải biết cách tự tạo và giải phóng không gian cho các đối tượng mà chúng ta đang sử dụng.

Phương pháp

Trong Objective-C, có 2 phương pháp để quản lý bộ nhớ, thứ nhất là dùng reference và thứ hai là dùng garbage collection. Bạn cứ nghĩ đơn giản là 2 cách thức theo kiểu là tự làm hoặc tự động theo môi trường của Objective-C, cụ thể reference counting là chúng ta phải tự làm còn garbage collection là cơ chế tự động và tự động quản lý bộ nhớ trong chương trình của chúng ta. Một lưu ý quan trọng là garbage collection không hoạt động trên iPhone, đó là lý do tại sao chúng tôi sẽ không tập trung nhiều vào phương pháp này. Nếu bạn muốn phát triển chương trình dành cho MacOS, bạn có thể tham khảo thêm các tài liệu trên website dành cho Apple Developer.

Cú pháp (Syntax)

Có nhiều cách thức khác nhau để tạo ảnh hưởng tới việc quản lý bộ nhớ. Trước hết, khi bạn tạo một đối tượng bằng cách sử dụng phương thức “alloc” (tạo mới hoặc copy) thì thực chất là bạn đã cấp cho nó một ô nhớ có thể chứa một sự thể hiện cho đối tượng đó và bạn sẽ là người quản lý đối tượng đó. Điều này cũng đúng trong trường hợp bạn dùng phương thức “retain”. Sau khi bạn tạo đối tượng xong rồi nếu bạn gọi phương thức release, hoặcautorelease (sẽ nói thêm về điều này sau) của đối tượng đó, bạn không còn có quyền quản lý đối tượng hoặc đảm nhiệm những công việc liên quan đến đối tượng đó nữa hay đơn giản là toàn bộ ô nhớ dành cho đối tượng đã khởi tạo sẽ bị giải phóng. Đoạn mã lệnh sau sẽ minh họa quá trình alloc một đối tượng:
Car *myCar = [Car alloc];
Sau khi chạy câu lệnh này thì chúng ta sẽ chịu trách nhiệm quản lý đối tượng myCar và tự xây dựng quá trình release (hoặc autorelease) đối tượng trong giai đoạn sau khi không cần sử dụng nó nữa. Điều quan trọng cần lưu ý rằng nếu bạn cố tình tiến hành thao tác release một đối tượng đã được thiết lập để autorelease thì ứng dụng ứng dụng của bạn sẽ lỗi.
Khi chúng ta tạo ra một đối tượng bằng cách sử dụng phương thức alloc, đối tượng xe của chúng ta sẽ có giá trị đếm là 1, có nghĩa là nó sẽ không được deallocate. Câu lệnh sẽ như sau:
[myCar retain];
Sau đó, khi có đối tượng mới được tạo, giá trị đếm của chúng ta sẽ tăng lên là 2 còn khi một trong những đối tượng được tạo không còn tồn tại nữa thì giá trị đếm lại giảm đi 1. Chỉ cho đến khi giá trị đếm đó về thành 0 thì đối tượng car mới được deallocate.

Khối lệnh autorelease

Khi bạn đã tạo ra một project mới trong Xcode, bạn có thể nhận thấy một số đoạn mã lệnh xuất hiện theo mặc định ví dụ như khối autorelease. Từ những bài trước chúng ta đã gặp nhưng tạm thời bỏ qua và bây giờ là thời điểm ta sẽ tìm hiểu cụ thể xem khối lệnh đó làm gì? Dưới đây là khối lệnh mặc định được thêm vào file main.m:
hoặc bạn có thể chủ động xây dựng kịch bản cho autorealease như sau:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[pool drain];
Trong đoạn mã trên ta sẽ thấy khi cần tạo ra khối lệnh xử lý autorelease thì ở trong câu lệnh thứ nhất chúng ta sẽ tạo một đối tượng từ lớp NSAutoReleasePool tên là pool và và câu lệnh thứ 2 sẽ kết thúc khối lệnh xử lýautorealse với lời gọi phương thức drain của đối tượng pool. Các câu lệnh mà khai báo trong phạm vi của 2 câu lệnh trên sẽ chịu ảnh hưởng của quá trình autorelease và cụ thể là chúng ta sẽ thấy nếu như các đối tượng được khởi tạo trong phạm vi này nếu như mà không còn có tham chiếu đến nó nữa thì nó sẽ tự động được release ra khỏi bộ nhớ mà chúng ta không cần phải tự viết thao tác release cho từng đối tượng.

Giá trị retainCount

Trước khi chúng tôi kết thúc, chúng ta hãy nhìn vào một cái gì đó mà có thể giúp làm cho bộ nhớ một chương quản lý dễ dàng hơn. Cho đến bài này chúng tôi đã tạo ra đối tượng và chúng tôi cũng biết có bao nhiêu bản thể hiện của đối tượng một đối tượng, nhưng làm thế nào để chỉ ra con số cụ thể đó? Đơn giản thôi, trên đối tượng thể hiện của chúng ta có một thuộc tính là retainCount và việc còn lại là ta chỉ cần in giá trị đó ra.
NSLog (@"retainCount for car object:% d", [myCar retainCount]);
retainCount trả về một số nguyên, vì vậy chúng tôi sử dụng %d để hiển thị giá trị trong phần định dạng.

Tổng kết

Thực sự việc quản lý bộ nhớ đối với hầu hết các ngôn ngữ đều là những vấn đề khá hóc búa. Một bài học chưa thể hướng dẫn chi tiết mọi vấn đề liên quan đến quản lý bộ nhớ. Vì vậy, chúng tôi có lời khuyên với những bạn mới học nên tạm cứ sử dụng những cơ chế tự động có sẵn trong Objective-C và khi đã có kinh nghiệm thì chúng ta sẽ đọc thêm tài liệu để tìm hiểu kỹ hơn về vấn đề này.
Đến đây là kết thúc bài học thứ 5 và để có thể tìm hiểu thêm một số chức năng mở rộng của những lớp thuộc framework Cocoa Touch (giúp cho các bạn muốn phát triển ứng dụng trên iPhone sau này) xin mời các bạn đọc bài học cuối cùng trong seri này.

Lưu ý:Series 6 bài viết về lập trình Objective-C này được sưu tầm từ nguồn trang:http://az4you.wordpress.com. Loạt bài viết nhằm phục vụ cho các bạn những kiến thức cơ bản ban đầu trước khi bắt tay vào học lập trình ứng dụng cho iOS (iPhone/iPad). ICTSharing xin thay mặt những người yêu lập trình Objective C gửi lời cảm ơn tới các tác giả gốc của các bài viết này! Các bạn cần lưu ý, dù là lập trình bằng bất kỳ ngôn ngữ nào, cho thiết bị nào thì nguyên lý cơ bản của nó cũng không có nhiều sự khác biệt, vì thế nếu bạn đã nắm vững một ngôn ngữ thì các ngôn ngữ còn lại sẽ không quá khó khăn nếu bạn thực sự tập trung. Trong thời gian chờ đợi ICTSharing ra mắt các video về hướng dẫn lập trình trên iOS, các bạn hãy tập trung nắm vững các phần cơ bản của ngôn ngữ Objective-C nhé.

«
Bài sau
Newer Post
»
Bài trước
Older Post

Bình luận

No comments :