Theo quy ước trong Cocoa và Cocoa-touch, bất kỳ đối tượng nào được tạo bằng cách sử dụng [[SomeClass alloc] initX]
hoặc [SomeClass newX]
được tạo với số lần giữ lại. Bạn chịu trách nhiệm gọi [someClassInstance release]
khi bạn đã hoàn tất với phiên bản mới của mình, thường là trong phương thức dealloc
của bạn.
Trường hợp này trở nên khó khăn là khi bạn chỉ định đối tượng mới của mình cho thuộc tính thay vì biến mẫu. Hầu hết các thuộc tính được định nghĩa là retain
hoặc copy
, có nghĩa là chúng sẽ tăng số lượng lưu giữ của đối tượng khi được đặt hoặc tạo bản sao của đối tượng, để nguyên bản gốc.
Trong ví dụ của bạn, bạn có thể có này trong tập tin .h
của bạn:
@property (retain) MyObject *editMyObject;
Vì vậy, trong ví dụ đầu tiên của bạn:
// (2) property setter increments retain count to 2
self.editMyObject =
// (1) new object created with retain count of 1
[[MyObject alloc] init];
// oops! retain count is now 2
Khi bạn tạo Ví dụ mới của bạn MyObject
sử dụng alloc
/init
, nó có số lần giữ lại. Khi bạn gán phiên bản mới cho self.editMyObject
, bạn đang thực sự gọi phương thức -setEditMyObject:
mà trình biên dịch tạo cho bạn khi bạn @synthesize editMyObject
. Khi trình biên dịch thấy self.editMyObject = x
, trình biên dịch sẽ thay thế nó bằng [self setEditMyObject: x]
.
Trong ví dụ thứ hai của bạn:
MyObject *temp = [[MyObject alloc] init];
// (1) new object created with retain count of 1
self.editMyObject = temp;
// (2) equivalent to [self setEditMyObject: temp];
// increments retain count to 2
[temp release];
// (3) decrements retain count to 1
bạn giữ cho đối tượng mới của bạn đủ dài để phát hành nó, do đó giữ lại đếm được cân bằng (giả sử bạn phát hành nó trong phương thức dealloc
của bạn).
Xem thêm Cocoa strategy for pointer/memory management
Nguồn
2009-03-05 00:37:27
Ba câu trả lời hay. Lưu ý chắc chắn ai cũng đưa ra câu trả lời. – 4thSpace