[Bài Học Số 3] Cơ Bản Objective Cx - Pdf 17

Quản lý bộ nhớ
Quản lý bộ nhớ là tiến trình xử lý việc khởi tạo vùng nhớ cho ứng dụng, sử dụng nó và giải
phóng nó khi ta đã hoàn thành công việc. Một chương trình quản lý bộ nhớ tốt sẽ sử dụng ít
vùng nhớ nhất có thể. Quản lý bộ nhớ là một vấn đề rất quan trọng trong lập trình. Một vấn
đề thường hay gặp phải đó là leak memory, khi chúng ta khởi tạo mà không giải phóng vùng
nhớ. Điều này có thể dẫn tới việc lãng phí bộ nhớ hoặc nghiêm trọng hơn là out of memory
và dẫn tới crash chương trình.
Objective-C cung cấp 3 cách quản lý bộ nhớ
• Manual retain-release (MRR) hoặc có thể gọi là Manual Reference Counting (MRC) có nghĩa
là chúng ta sẽ tự quản lý bộ nhớ bằng cách đánh dấu quá trình sử dụng của các object mà
ta có. Cụ thể là ta sẽ đếm việc khởi tạo, sử dụng và giải phóng object trong chương trình.
• Autiomatic Reference Counting (ARC), hệ thống sẽ dùng bộ đếm tương tự như MRR nhưng
nó sẽ thêm vào method quản lý bộ nhớ tự động tại thời điểm compile. Ta nên sử dụng ARC
cho các project mới
• Garbage Collection (GC), hệ thống sẽ tự động lưu vết và tự động giải phóng vùng nhớ của
object không cần thiết nữa. Nó sử dụng kỹ thuật quản lý bộ nhớ khác MRR hoặc ARC tuy
nhiên GC chỉ hỗ trợ Mac OS X mà không hỗ trợ iOS
Reference Counting
Khi một object được sinh ra, Objective-C sử dụng một kỹ thuật gọi là reference counting
hoặc đôi khi gọi là retain counting để theo vết vòng đời của object. Mỗi object sẽ có một số
interger đánh dấu nó, được biết như là reference count hoặc retain count. Khi một đoạn
code nào đó tác động tới object, đoạn code đó sẽ tăng retain count, khi kết thúc đoạn code
và không sử dụng object nữa, nó sẽ giảm retain count. Khi retain count về 0 cũng có nghĩa
là nó không sử dụng nữa và lúc này nó sẽ bị hủy khỏi bộ nhớ.
Khi object được khởi tạo bằng các từ khóa như alloc, new hoặc xử lý message copy, retain
count của object sẽ tự động là 1. Để tăng retain count lên, ta gửi retain message cho
object. Để giảm retain count ta gửi release message.
Khi retain count của object về 0 và object cần được hủy, Objective-C sẽ tự động gửi dealloc
message cho object. Ta có thể override dealloc method trong object để release resource nào
mà ta muốn. Không nên gọi dealloc method trực tiếp. Để có thể biết được retain count hiện
tại, ta gửi retainCount message. Tóm lại ta có 3 method quan trọng như sau

PHP Code:
int main(int argc, const char *argv[])
{
RetainTracker *tracker = [RetainTracker new];
//count: 1
[tracker retain]; // count: 2
[tracker retain]; // count: 2
[tracker release]; // count: 1
[tracker retain]; // count: 2
[tracker release]; // count: 1
[tracker release]; // count: 0, dealloc
return (0);
}
Qua ví dụ trên, ta thấy rõ cơ cấu quản lý bộ nhớ của Objective-C như thế nào.
Object Ownership
Cho tới giờ việc quản lý bộ nhớ mà ta biết chưa có gì quá phức tạp, nó đi theo chu trình từ
lúc khởi tạo thông qua bộ đếm retain count và dealloc khi về 0. Vấn đề sẽ thực sự trở nên
rắc rối khi ta đề cập tới khái niệm object ownership.
Một object với instance variables trỏ tới một object khác được gọi là own object khác. Ta có
object CarParts có các variables engine trỏ tới object engine và tires trỏ tới các objects tires.
Ví dụ trong object CarParts có methods
PHP Code:
-(void)setEngine: (Engine*) newEngine;
Và trong hàm main() ta gọi
PHP Code:
PHP Code:
Engine *engine = [Engine new];
[car setEngine: engine];
Trong trường hợp trên ta sẽ gặp rắt rối nảy sinh khi object engine vừa nằm trong hàm
main() vừa được sử dụng trong object car (kiểu CarParts) và khó xác định khi nào thực sự

{
[engine release];
engine=[newEngine retain]; //chú ý retain trả về id của Engine
}
Cách code trên đưa ra giải pháp release ngay engine variable trước khi nhận object Engine
mới. Nhìn có vẻ hợp lý, tuy nhiên đoạn code trên sẽ gặp vấn đề cực kỳ lớn nếu như ta gặp
phải đoạn code dưới đây
PHP Code:
PHP Code:
Engine *engine = [Engine new]; //count: 1
Car *car1 = [Car new];
Car *car2 = [Car new];
[car1 setEngine: engine]; //count: 2
[engine release]; //count: 1
[car2 setEngine: [car1 engine]]; //count: 0
AutoRelease
AutoRelease là cơ chế mà ta không cần phải quan tâm đến việc release đối tương, nó sẽ tự
động giảm retain count xuống và release khi ta không sử dụng nó nữa. Để khai báo
autorelease ta sử dụng như sau :
PHP Code:
[PHP]Car *car1 = [[[Car alloc] init] autorelease];
[/PHP]
Tuy nhiên chúng ta nên cẩn thận đối với loại này. Ví dụ hàm ta có 1 đối tượng car1 trong
class và nó được khai báo như trên trong phương thức A(), ở phương thức B() ta sử dụng
đối tượng này sẽ bị crash do khi chạy hết hàm A() thì đối tượng car1 đã bị release.
Protocols
Khai báo các protocols methods có thể được implement trong bất cứ class nào. Protocols có
thể hữu ích trong ba trường hợp sau:
• Khai báo method mà class khác dự định sẽ thực thi
• Khai báo interface cho một object và che dấu nội dung bên trong nó

đương với dòng lệnh
PHP Code:
PHP Code:
-(float)value;
-(void)setValue:(float)newValue;
Khai báo Property Attributes
Chúng ta có thể thêm vào một property các attributes theo cú pháp @property(attribute1,
attribute2,…). Nếu ta dùng @synthesize (trong phần implementation) để nói cho compiler
tạo các accessor methods truy cập property, compiler sẽ tự động xử lý hoàn toàn. Tuy nhiên
nếu ta tự xử lý accessor methods, ta phải chắc rằng nó phù hợp với những gì ta đã khai báo
trong interface, kể cả các attributes. Ta sẽ coi rõ trong phần implementation.
Accessor Method Names


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status