2009-06-25 27 views
6

Tôi có một lớp mà tôi đang đóng gói ABRecordID với và khi nó được sử dụng như một chìa khóa để thêm vào NSMutableDictionary, tôi nhận được thời gian chạy ngoại lệ:NSInvalidArgumentException/copyWithZone ngoại lệ với NSMutableDictionary

"NSInvalidArgumentException: *** - [MyRecordId copyWithZone:]: chọn không được công nhận gửi đến dụ"

MyRecordId khai báo là:

@interface MyRecordId : NSObject { 
    ABRecordID abRecordId; 
} 

-(id)initWithId:(ABRecordID)anABRecordId; 
@property (nonatomic) ABRecordID abRecordId; 

@end 

Thêm vào từ điển:

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
MyRecordId *recordId = [[MyRecordId alloc] initWithId:anABRecordId]; 
[dict setObject:@"hello" forKey:recordId]; 

Dòng cuối cùng gây ra ngoại lệ .. Tôi biết rằng bạn không thể lưu trữ các loại phi vật thể như là chìa khóa cho một cuốn từ điển nhưng tôi nghĩ rằng gói nó trong lớp NSObject có nguồn gốc sẽ làm cho nó ổn.

Tôi có được phép lưu trữ ABRecordID trong các đối tượng khác không? Tôi có nên làm gì khác không?

Trả lời

7

Sử dụng NSNumber để lưu trữ các ABRecordID trong một lớp obj-C:

[dict setObject:@"hello" forKey:[NSNumber numberWithInt:recordId]]; 

để có được những recordID một lần nữa, làm:

recordId = [[dict objectForKey:@"hello"] intValue]; 
6

Phím NSDictionary cần triển khai giao thức NSCopying. Đó là lý do tại sao nó cho bạn biết đối tượng của bạn không phản ứng với copyWithZone:.

6

Lớp đối tượng bạn sử dụng làm giá trị khóa phải tuân theo giao thức NSCopying. Về cơ bản, nó nên triển khai phương pháp copyWithZone:.

Thay vì sử dụng lớp của riêng bạn để bọc biến không đối tượng, bạn nên sử dụng lớp NSValue, được thiết kế cho mục đích này và hỗ trợ giao thức NSCopying.

+0

Tôi không biết rằng NSValue phù hợp nhất với mục đích này. Tôi sẽ sử dụng trình khởi tạo nào để xây dựng nó bằng 'ABRecordID'? –

+2

Tôi sẽ có giá trị 'NSValueWithNonretainedObject', nên làm việc cho bạn. Chỉ cần ghi nhớ rằng nó sẽ không giữ lại đối tượng của bạn cho bạn tất nhiên ... – Chris

0

Bạn cũng có thể sử dụng NSNumber cho mục đích này vì nó được kế thừa từ NSValue.

0

Diederik đang đi đúng hướng, nhưng với kiểu ABRecordID, tôi khuyên bạn nên sử dụng NSNumber (một lớp con NSValue). Bạn sẽ sử dụng -initWithInt: cho ABRecordIDint32_t.

1

Đối với mã hóa thách thức như tôi, chắc chắn các đối số để setObject là đúng cách xung quanh. Tôi chỉ lãng phí giờ vào lỗi này trước khi tôi nhận thấy tôi đã đảo ngược chúng!

+0

christ ngọt ngào, điều này đã được chính xác vấn đề của tôi quá, nhờ – ardnew

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