2010-04-26 29 views
6

Giả sử tôi có một lớp xem bảng liệt kê 100 đối tượng Foo. Nó có:Có thể cho nhiều đối tượng giữ lại cùng một đối tượng trong Objective-C/Cocoa không?

 
@property (nonatomic, retain) NSMutableArray* fooList; 

và tôi điền vào nó với Foos như:

 
self.fooList = [NSMutableArray array]; 
while (something) { 
    Foo* foo = [[Foo alloc] init]; 
    [fooList addObject:foo]; 
    [foo release]; 
} 

Câu hỏi đầu tiên: vì NSMutableArray được đánh dấu là giữ lại, có nghĩa là tất cả các đối tượng bên trong nó được giữ lại quá? Tôi có chính xác thêm foo và phát hành bản sao cục bộ sau khi nó được thêm vào mảng không? Hoặc tôi đang thiếu một cuộc gọi giữ lại?

Sau đó, nếu người sử dụng chọn một hàng cụ thể trong bảng và tôi muốn hiển thị một cách chi tiết Foo xem tôi gọi:

 
FooView* localView = [[FooView alloc] initWithFoo:[self.fooList objectAtIndex:indexPath.row]]; 
[self.navigationController pushViewController:localView animated:YES]; 
[localView release]; 

Bây giờ lớp FooView có:

 
@property (nonatomic, retain) Foo* theFoo; 

vì vậy bây giờ cả hai mảng đang nắm giữ Foo đó cũng như FooView. Nhưng điều đó có vẻ ổn chứ? Khi người dùng truy cập nút dealloc ở phía sau sẽ được gọi trên FooView và [theFoo release] sẽ được gọi. Sau đó, một nút quay lại khác là hit và dealloc được gọi trên lớp tableview và [fooList release] được gọi.

Bạn có thể tranh luận rằng lớp FooView nên có:

 
@property (nonatomic, assign) Foo* theFoo; 

vs giữ lại. Nhưng đôi khi lớp FooView được gọi với một Foo không có trong một mảng. Vì vậy, tôi muốn đảm bảo có hai vật thể đang cầm trên cùng một vật thể khác.

Trả lời

4

Như những người khác nói, những gì bạn đang làm là chính xác và mã có vẻ đúng với tôi. Tôi có hàng chục tài liệu tham khảo cho cùng một đối tượng trong mã của tôi và miễn là tôi đã cân bằng tất cả các lưu giữ và phát hành, mọi thứ hoạt động tốt.

Để thêm chi tiết hơn một chút ...bạn yêu cầu:

vì NSMutableArray được đánh dấu là giữ lại, điều đó có nghĩa là tất cả các đối tượng bên trong cũng được giữ lại?

Đây là hai điều khác nhau. Tất cả các lớp sưu tập (Từ điển, Mảng, Bộ) tự động giữ lại những thứ bạn thêm vào, và giải phóng các đối tượng nội dung của chúng khi đối tượng thu thập được phân phối lại. (Trong trường hợp của NSMutableArray, đối tượng nội dung được giải phóng hoặc nếu bạn loại bỏ nó khỏi mảng hoặc khi bạn deallocate toàn bộ mảng.)

Điều này không liên quan gì đến việc chính đối tượng thu thập được giữ lại hoặc gán bất động sản. Điều duy nhất cần cân nhắc là nếu chính sách của bạn cho thuộc tính đối tượng thu thập không đúng, nó có thể được phát hành sớm hay muộn hơn bạn nghĩ và mọi thứ có thể mất cân bằng.

Khi người khác nói ... hãy đọc memory management guide và thực hành. :) Oh, và đọc mã của người khác quá từ quan điểm này và cố gắng hiểu làm thế nào/tại sao họ đang làm quản lý bộ nhớ của họ.

Một điều nhỏ khác ... cho mỗi thuộc tính được giữ lại, đảm bảo bạn có cuộc gọi phát hành theo phương thức dealloc của đối tượng.

+0

Typo: "... và giải phóng đối tượng nội dung của chúng khi đối tượng bộ sưu tập được giải phóng". Đối tượng trong bộ sưu tập không được phát hành cho đến khi bộ sưu tập được * deallocated *. – JeremyP

+0

Cảm ơn, đã sửa. Mặc dù bạn có thể lập luận rằng bằng cách "phát hành", tôi có nghĩa là "bản phát hành cuối cùng, theo đó giữ lại số đếm về 0, điều đó gây nên sự cố": P nhưng chỉ nói dealloc rõ ràng hơn trong ngữ cảnh đó. – Jaanus

4

Có, không sao. Đó là toàn bộ quan điểm của hệ thống quản lý bộ nhớ đếm tham chiếu.

5

Để trả lời câu hỏi chính của bạn, có bạn có thể nhiều đối tượng giữ lại một thể hiện. Đó chính xác là điểm quản lý bộ nhớ tham chiếu. Có một cái nhìn tại Cocoa Memory Management Programming Guide để biết thêm thông tin. Sau đó đọc lại nó. Nó có tất cả các câu trả lời và sẽ là người bạn tốt nhất của bạn.

Về cơ bản, gửi tin nhắn -retain cho biết người gửi "sở hữu" người nhận theo nghĩa rằng người nhận không nên deallocated cho đến khi tất cả chủ sở hữu đã công bố quyền sở hữu của họ. Do đó, các cá thể cá thể không cần phải biết (cũng không nên quan tâm) cho dù các chủ sở hữu khác tồn tại. Giữ lại bất cứ thứ gì bạn cần để giữ lại và giải phóng nó khi bạn hoàn thành nó. Khi tất cả chủ sở hữu đã phát hành quyền sở hữu của họ, một intsance có thể được deallocated.

Trên một mặt lưu ý,

@property (retain,readwrite) NSMutableArray *myArray; 

tuyên bố rằng các lớp tuyên bố sở hữu này sẽ giữ lại dụ NSMutableArray. NSArray, NSDictionaryNSSet (và các lớp con có thể thay đổi) luôn giữ nguyên nội dung của chúng.

Các vấn đề liên quan