… Quản lý bộ nhớ đối với biến: Trước khi đi vào cụ thể mình có lưu ý một số thuật ngữ sau tiện cho sử dụng.. Strong trỏ đến đối tượng và có quyền sở hữu đối tượng, nghĩa là có quyền quyế
Trang 1QUẢN LÝ BỘ NHỚ TRONG OBJECITVE C
(MEMORY MANAGEMENT)
Một vấn đề rất được quan tâm trong lập trình ios là quản lý bộ nhớ (Memory
Management), chắc các bạn cũng từng đặt câu hỏi là vì sao phần mềm Iphone,
Mac os, IPad… chạy rất mượt sau một thời gian dài sử dụng Đó là sự khác biệt rất tuyệt vời.Đối với các ngôn ngữ, Android , Windows phone… quản lý bộ nhớ, giải phóng
bộ nhớ, thu rọn rác hoàn toàn tự động
Các phương pháp quản lý bộ nhớ trong Objective C:
chúng ta sẽ tự quản lý bộ nhớ bằng cách đánh dấu, theo vết vòng đời của
object 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
dùng bộ đếm tương tự như MRC nhưng nó sẽ thêm vào phương thức quản lý bộ nhớ tự động tại thời điểm compile
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 với MRC và ARC, tuy nhiên GC chỉ hỗ trợ Mac OS X mà không hỗ trợ iOS
IOS bây giờ sử dụng trình ARC để giải phóng bộ nhớ, và rọn rác Tuy nhiên chúng ta vẫn quản lý từng biến thuộc tính cho phép tham chiếu đến đối tượng như thế nào? khi nào được phép giải phóng? …
Quản lý bộ nhớ đối với biến:
Trước khi đi vào cụ thể mình có lưu ý một số thuật ngữ sau tiện cho sử dụng
Lưu ý:
1 Trỏ đến = tham chiếu đến
2 Sở hữu đối tượng = có quyền quyết định đến sự tồn tại của đối tượng
Strong trỏ đến đối tượng và có quyền sở hữu đối tượng, nghĩa là có quyền quyết định đến sự tồn tại của đối tượng
– Mặc định là strong: Khi bị gán mới nghĩa là trỏ đến đối tượng mới thì ô nhớ chứa
đối tượng cũ bị giải phóng
1 <span style= "font-size: 14pt;" > <span style= "font-size: 10pt;" >strong NSArray *Arr=@ [ @ ( 1 )] ;
Trang 22 Arr=@ [ @ ( 10 )] ;//Arr trỏ đến vùng nhớ mới khi đó Vùng nhớ cũ bị giải phóng.</span></span><span style="font-size: 10pt;">
3 NSLog( @ "%@" ,Arr ) ;</span>
Ở đây Arr là biến strong, kiểu dữ liệu NSArray, trỏ tới vùng nhớ chứa giá trị:@[@(1)],
sở hữu vùng nhớ
Arr=@[@(10)]; Arr trỏ đến vùng nhớ chứa giá trị @[@(10)] dẫn tới vùng nhớ chứa giá trị @[@(1)] không có ai trỏ tới và sẽ bị giải phóng
=>Ngay lật tức vùng nhớ cũ bị ARC giải phóng
kết quả: Arr=10
– Đối với strong gán bằng strong :
1 // biến kiểu strong gán strong
5 NSLog( @ "%@" ,Arr2 ) ;
ở đây strong Arr1 trỏ vào vùng nhớ của đối tượng có giá trị @[@(1)], và có quyền sở hữu đối tượng đó
Arr2=Arr1 => Arr2 trỏ đến cùng vùng nhớ của đối tượng Arr1 trỏ với, và cũng có quyền
sở hữu như nhau Vì thế khi gán lại Arr1=@[(10)] vùng nhớ cũ không bị giải phóng Kết quả Arr2=1;
-Đối với weak gán bằng strong:
Weak trỏ tới đối tượng , nhưng không có quyền sở hữu đến đối tượng, nghĩa là không
có quyền quyết định đến sự tồn tại của đối tượng
thêm đoạn mã sau:
1 // kiểu weak gán strong
4 Arr3=@ [ @ ( 10 )] ;
5 NSLog( @ "%@" ,Arr4 ) ;
ở đây strong Arr3 trỏ vào vùng nhớ của đối tượng có giá trị @[@(1)], và có quyền sở hữu đối tượng đó
Trang 3weak Arr4 = Arr3 => Arr 4 trỏ đến cùng vùng nhớ của đối tượng Arr3, nhưng không có quyền sở hữu vùng nhớ đó, chỉ tham chiếu gián tiếp thông qua Arr3
Khi Arr3=@[@(10)]; thì Arr3 trỏ đến vùng nhớ chứa đối tượng mới, mà Arr3 có quyền
sở hữu vùng nhớ cũ dẫn tới vùng nhớ cũ bị giải phóng , dẫn tới Arr4=nil rỗng
kết quả Arr4=nil;
unsafe_unretained: unsafe_unretained luôn trỏ về vùng nhớ cũ.khi vùng
nhớ bị giải phóng nó vẫn trỏ đến vùng nhớ giải phóng, có thể dẫn đến crash chương trình khi vùng nhớ bị xoá.
Tuy nhiên :giải phóng không có nghĩa là vùng nhớ bị xoá như kiểu thùng
rác quản lý trong máy tính lưu lại một thời gian sau đó mới xóa
Kiểu gán này không làm tăng vùng nhớ, dùng gán biến tạm.
3 Arr5=@ [ @ ( 10 )] ;
4 NSLog( @ "%@" ,Arr6 ) ;
Thằng Arr6 luôn trỏ về vùng nhớ cũ của Arr5 cho dù Arr5 đã giải phóng vùng nhớ cũ May mắn kết quả: Arr6=1
Tuy nhiên nếu để một thời gian không sử dụng biến này có thể gây crash chương trình
do vùng nhớ đã được giải phóng lưu lại trong thùng rác mà chưa bị xoá, sau một thời gian đầy thùng rác bị xoá thì gây crash chương trình
Quản lý vùng nhớ đối với property :
Tính đồng bộ hóa thread:
thể thay đổi giá trị thuộc tính, dẫn tới không an toàn
Lưu ý:Nếu chỉ có 1 luồng truy cập vào biến thì tốc độ nhanh
gán giá trị chỉnh sửa xong mới cho phép thread khác sử dụng biến đó để chỉnh sửa
Lưu ý:Truy cập chậm hơn nonatomic nếu chỉ có 1 luồng do có cơ chế khóa mặc định khi có nhiều luồng truy cập!
Trang 4Tính cho phép đọc ghi dữ liệu vào thuộc tính Property: (IVar đọc ghi bình
thường)
readwrite (default): cho phép đọc, ghi vào thuộc tính
đọc ghi bình thường”
Thay đổi tên mặc định cho hàm get, set Property:
Do tên set get thường là tính từ, thuộc tính là danh từ, or ta muốn quản lý lại get
set, nên ta cần nhu cầu thay đổi tên get set mặc định
@property(assign,getter=isAge,setter=setIsAge:) int age; sử dụng “getter = tên getter mới”, “setter=tên setter mới:”
Quản lý bộ nhớ đối với thuộc tính đối tượng
Đối với thuộc tính là kiểu đối tượng trong Objective C:
Lưu ý: nhắc lại
1 Trỏ đến = tham chiếu đến
2 Sở hữu đối tượng = có quyền quyết định đến sự tồn tại của đối tượng
3 Strong pointer và weak pointer đề cập đến việc tham chiếu mạnh hay yếu tới object
đó.biến iVar sẽ là weak pointer
đối tượng đó.weak thường đi kèm với một đối tượng kiểu strong.” biến iVar sẽ là strong pointer, tương đương với retain
Ví vụ minh họa: Ta khai báo một class sinhVien như sau:
2 @property( strong,nonatomic ) NSArray *model;
3 - void ) infor;
4 @end
Thực thi hàm infor:
2 - void ) infor {
3
4 NSArray *arr=@ [ @ ( 0 )] ;
Trang 55 self.model=arr;
7 NSLog( @ "strong : %@" ,self.model ) ;
8 }
9 @end
Tương tự kiểu strong trong biến mà mình đã giải thích ở trên: kết quả model=0 có cùng quyền sở hữu do tham chiếu mạnh
nếu ta thay đổi strong thành weak
@property(weak,nonatomic) NSArray *model;
khi đó model=nil do tham chiếu yếu không có quyền sở hữu đối tượng Tương tự như weak trong biến mà mình đã giải thích ở trên
thuộc tính là đối tượng
copy: cố gắng copy khi property được gán
copy là sao chép toàn bộ đối tượng của property được gán! xong lưu đối tượng
đó vào vùng nhớ mới
Copy phát huy tác dụng khi muốn tạo một bản sao rồi chỉnh sửa mà không ảnh hưởng đến đối tượng cũ Sử dụng chủ
yếu NSMutableDictionary, NSMutableString, NSMutableArray, lấy bản sao dữ liệu rồi tuỳ chỉnh
Ví dụ sau:
2 @property( copy,nonatomic ) NSMutableArray *model;
3 - void ) infor;
4 @end
Thực thi hàm infor:
2 - void ) infor {
3
7 NSLog( @ "strong : %@" ,self.model ) ;
8 }
9 @end
Trang 6Khi giải phóng vùng nhớ của arr=nil, kết quả: model=0 do taon bản sao trỏ đến vùng nhớ mới nên vùng nhớ cũ bị giải phóng không ảnh hưởng đến kết quả model
Đối với thuộc tính là kiểu nguyên thủy trong C:
dùng nhẹ nhàng hơn rất nhiều, vì nó dùng cho kiểu nguyên thủy C
Chú ý: kiểu nguyên thủy C khi khai báo luôn trỏ vào một vùng nhớ mà không bị thay đổi vùng nhớ, chỉ tham chiếu giá trị cho biến chính vì thế Assign mới phát huy được ưu điểm là trỏ vào một vùng nhớ