IOS Programming - QUẢN LÝ BỘ NHỚ TRONG OBJECTIVE-C p2


QUẢN LÝ BỘ NHỚ TRONG OBJECTIVE-C


4. Từ khóa và ví dụ

• alloc hoặc new  
Mục đích : 
Cấp phát bộ nhớ cho đối tượng.
Reference count bằng 1
Ví dụ:
NSString *str = [[NSString allocinit];
NSString *str = [NSString new];

• copy
Mục đích : 
Cấp phát bộ nhớ cho đối tượng thông qua một đối tượng khác.
Reference count : bằng 1
Ví dụ:
NSString *str = [someString copy];

 retain  
Mục đích : 
Gọi khi ta cần sử dụng một đối tượng, mà đối tượng đó đã được cấp phát ở đâu đó, ta không chắc là tại thời điểm ta sử dụng thì đối tượng đó có bị release hay không. Gọi retain giống như ta thông báo cho chủ sở hữu của nó là “Đừng xóa nó cho đến khi tôi sử dụng nó xong nhé !”. Khi gọi retain thì lúc này chúng ta là chủ sở hữu mới của nó(bên cạnh chủ sở hữu cũ). Khi nào sử dụng xong ta cần phải release nó.
Reference count : tăng thêm 1
Ví dụ:
NSString *str = [[NSString allocinitWithString:@”Hello”];
NSString *str2 = str;        
[str release];               
//Sau vài giây thì str2 không còn lưu đúng nội dung
Trong ví dụ trên, biến str2 chỉ đơn giản là trỏ đến vùng nhớ của biến str, một khi ta giải phóng biến str thì biến str2 sẽ lưu không còn đúng nội dung nữa. Giải pháp :
NSString *str = [[NSString allocinitWithString:@”Hello”];
NSString *str2 = [str retain];
[str release];
//str2 vẫn còn lưu đúng nội dung cho tới khi ta giải phóng nó
[str2 release];

 release
Mục đích
Báo cho hệ thống biết là ta đã sử dụng xong 1 đối tượng nào đó và cần giải phóng nó. Đối tượng sẽ thực sự được giải phóng chỉ khi không còn ai sở hữu nó nữa (reference count = 0)
Reference count : Giảm xuống 1 ngay lập tức.

 autorelease  
Mục đích
- Khi ta không muốn giải phóng một đối tượng nào đó ngay lập tức.
- Khi ta không muốn phải ghi nhớ lúc nào nên release những đối tượng mà ta đã cấp phát khi sử dụng xong.
- Khi ta muốn thêm một đối tượng vào autorelease pool.
Reference count : Giảm xuống 1 nhưng không ngay lập tức.

 Convenience methods
Khái niệm :
Là những phương thức static, dùng để cấp phát và khởi tạo đối tượng một cách trực tiếp. Đối tượng được tạo ra từ phương thức convenience gọi là autorelease object, và ta không sở hữu đối tượng này.
NSString *str2 = [NSString stringWithFormat:@”%d”, 4]; 
- Tất cả các autorelease objects  được tạo ra sẽ được thêm vào autorelease pool  hiện tại.

 Autorelease Pool  
Khái niệm : 
Là nơi chứa và giải phóng các autorelease objects . Khi autorelease pool  được giải phóng (thường là hết vòng lặp hay kết thúc hàm) thì các object nằm bên trong nó cũng sẽ được tự động giải phóng.
Khi nào nên sử dụng : 
- Khi ta muốn tự hủy một loạt các autorelease objects.
- Trong trường hợp cụ thể khi ta sử dụng nhiều biến tạm và muốn tránh phải cấp phát và release tất cả những biến này khi sử dụng xong.
- Hoặc ta không muốn đợi autorelease pool  của hệ thống được giải phóng, ta sẽ sử dụng đối tượng thuộc lớpNSAutoreleasePool

for (int i = 0; i < 99999; i++){       
  NSAutoreleasePool *pool = [[NSAutoreleasePool allocinit];
  NSString *str1 = [NSString stringWithFormat:@”%d”, i];
  NSString *str2 = [NSString stringWithFormat:@”%d”, i];      
  //...
  [pool release];//Các autorelease objects ở trên sẽ đc giải phóng
}
Như ví dụ trên đây, nếu như ta không dùng lớp NSAutoreleasePool  thì khi chạy hết 99999 vòng lặp, cácautorelease objects  nằm trong autorelease pool  mới được giải phóng, và điều đó sẽ gây ra hiện tượng tràn bộ nhớ.

 Hệ quả từ Autorelease Pool
Khi trong hàm ta sử dụng nhiều biến được cấp phát, và không muốn suy nghĩ lúc nào nên release biến này, lúc nào nên release biến kia, ta chỉ cần kẹp đoạn code giữa NSAutoreleasePool , rồi cho biến đó autorelease, sau đó ta vẫn sử dụng nó được bình thường.
NSAutoreleasePool *pool = [[NSAutoreleasePool allocinit];
Animal *animal = [[Animal allocinitWithName:@"Animal"];
[animal autorelease];     
Zoo *zoo = [[Zoo allocinit];
[zoo autorelease];
[zoo add:animal];     
[pool release];

Nhận xét

Bài đăng phổ biến