2012-01-05 13 views
20

Tôi muốn lưu trữ một tham chiếu yếu zeroing đến một đối tượng trong một NSDictionary. Đây là để tham chiếu đến một phụ huynh NSDictionary, vì vậy tôi có thể thu thập thông tin sao lưu một cấu trúc lớn mà không cần tìm kiếm.Đối tượng yếu trong một NSDictionary?

Tôi không thể sử dụng __weak tại đây; ngay cả khi tham chiếu cục bộ của tôi yếu, thì NSDictionary sẽ lưu trữ một tham chiếu mạnh mẽ đến đối tượng đã được tham chiếu yếu. Và, tất nhiên, NSDictionary không được có các đối tượng nil.

Tôi đang sử dụng iOS chứ không phải máy Mac, do đó, NSHashTable không khả dụng. Và tôi chỉ muốn một vật thể yếu đuối; phần còn lại vẫn nên mạnh mẽ.

(Tôi sẽ gửi câu trả lời của tôi, vì vậy tôi có một cái gì đó để đánh dấu như được chấp nhận nếu không có câu trả lời tốt hơn. Nhưng tôi hy vọng ai đó có một câu trả lời tốt hơn.)

+0

Tôi đã tạo [this] (https://gist.github.com/firelizzard18/6326536) làm từ điển lưu trữ các đối tượng dưới dạng tham chiếu yếu kém hiệu quả. Nó có thể được sửa đổi (và dọn dẹp) để phục vụ cho mục đích của bạn. –

Trả lời

35

Trong iOS 6+, bạn có thể sử dụng NSMapTable và chọn nếu bạn muốn các đối tượng và/hoặc khóa yếu hoặc mạnh.

+2

Rõ ràng câu trả lời tốt nhất cho hôm nay và tiến lên. Cảm ơn. –

+0

Bạn có phiếu bầu của tôi – Carina

+3

NSMapTable có thể không hoạt động như mong đợi: http://cocoamine.net/blog/2013/12/13/nsmaptable-and-zeroing-weak-references/ – nehz

14

Tôi đã giải quyết trên quy định một lớp "container" với một thành viên duy nhất, như thế này:

@interface Parent : NSObject 
@property (nonatomic, weak) id parent; 
@end 

@implementation Parent 

@synthesize parent = _parent; 

- (id)initWithParent: (id)parent; 
{ 
    if ((self = [super init])) { 
     _parent = parent; 
    } 
    return self; 
} 
@end 

Và sử dụng nó:

id parentRef = [[Parent alloc] initWithParent: parent]; 
[newElement setObject: parentRef forKey: ParentKey]; 

tôi nghĩ rằng điều này sẽ làm việc cho tôi, nhưng có vẻ như điên rằng không có cách nào tốt hơn được xây dựng trong nền tảng.

+0

Âm thanh như giải pháp duy nhất cho tôi - đó là cách tôi cũng đã thực hiện nó. Hoặc một 'NSValue' nhưng điều đó sẽ không bằng không. – mattjgalloway

+1

Tôi đang gặp vấn đề tương tự và tôi cũng nghĩ về một thùng chứa, tôi vẫn không cố gắng nhưng tôi đang cố gắng làm cho một cái gì đó gần với những gì bạn làm với khối 'id __weak weakObject = strongObject; [optionDict setValue: [Giá trị NSValueWithNonretainedObject: tmpObject] forKey: key]; 'vẫn cần phải tìm ra nếu nó hoạt động. – Andrea

+1

Nhận xét cũ nhưng tôi sẽ thêm nhận xét này cho khách truy cập mới. Những gì Andrea nói sẽ không hoạt động, từ điển sẽ giữ lại đối tượng. – Emanuel

6

Có cách tích hợp sẵn; chỉ cần sử dụng:

[array addObject:[NSValue valueWithNonretainedObject:object]]; 

Sau đó, để truy cập vào các đối tượng sau đó, sử dụng:

id object = [[array objectAtIndex:i] nonretainedObjectValue]; 

Nếu giá trị đã được phát hành kể từ khi bạn thêm nó sau đó "đối tượng" sẽ là một con trỏ không hợp lệ dưới iOS 4.x , và (tôi giả định) sẽ không nhỏ hơn 5.x khi bật ARC.

CHỈNH SỬA: giả định của tôi sai - nó không yếu dưới ARC (xem thảo luận bên dưới).

+3

Không, đó là một con trỏ lơ lửng. Nhưng cảm ơn cho ý tưởng. :) –

+0

Con trỏ lơ lửng không bao giờ nên được truy cập, mặc dù, như đối tượng của bạn là gần đến chết tại thời điểm đó. Vì vậy, truy cập vào phụ huynh ở đây nên là một lỗi anyway, mà trong trường hợp này không được ẩn bởi niling ra. – Eiko

+1

@Eiko, bạn đã sai. Đó là một trường hợp phổ biến cho mô hình quan sát viên. –