2012-05-29 15 views
17

Ứng dụng của tôi bị lỗi sau khi tôi gọi hàm addImageToQueue. Tôi đã thêm initWithObjects: forKeys: count: nhưng nó không giúp tôi.NSDictionary: phương thức chỉ được định nghĩa cho lớp trừu tượng. Ứng dụng của tôi bị lỗi

Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: '*** -[NSDictionary initWithObjects:forKeys:count:]: 
method only defined for abstract class. 
Define -[DictionaryWithTag initWithObjects:forKeys:count:]!' 

mã của tôi

- (void)addImageToQueue:(NSDictionary *)dict 
{ 
DictionaryWithTag *dictTag = [DictionaryWithTag dictionaryWithDictionary:dict]; 
} 

@interface DictionaryWithTag : NSDictionary 
@property (nonatomic, assign) int tag; 

- (id)initWithObjects:(id *)objects forKeys:(id *)keys count:(NSUInteger)count; 

@end 

@implementation DictionaryWithTag 

@synthesize tag; 

- (id)initWithObjects:(id *)objects forKeys:(id *)keys count:(NSUInteger)count 
{ 
return [super initWithObjects:objects forKeys:keys count:count]; 
} 
@end 
+1

Bạn không nên phân lớp NSDictionary. Tại sao bạn làm việc đó ? – giorashc

+0

Tôi muốn thêm thuộc tính thẻ. Đó là tính năng tuyệt vời. Có thể tôi cần phải thêm khóa mới vào một từ điển và không phân lớp NSDictionary. – Voloda2

Trả lời

38

Bạn subclassing NSDictionary? Đó không phải là một điều phổ biến để làm trong Cocoa-đất, có thể giải thích lý do tại sao bạn không nhìn thấy kết quả bạn mong đợi.

NSDictionary là một cụm lớp. Điều đó có nghĩa rằng bạn không bao giờ thực sự làm việc với một thể hiện của NSDictionary, mà là với một trong các lớp con riêng của nó. Xem mô tả của Apple về cụm lớp here. Từ tài liệu đó:

Bạn tạo và tương tác với các phiên bản của cụm giống như bất kỳ lớp nào khác. Tuy nhiên, đằng sau hậu trường, khi bạn tạo một thể hiện của lớp công khai, lớp trả về một đối tượng của lớp con thích hợp dựa trên phương thức tạo mà bạn gọi. (Bạn không, và không thể, hãy chọn lớp thực tế của cá thể.)

Thông báo lỗi của bạn là nếu bạn muốn phân lớp NSDictionary, bạn phải triển khai bộ lưu trữ phụ trợ của chính bạn cho nó (ví dụ bằng cách viết một bảng băm trong C). Nó không chỉ yêu cầu bạn khai báo phương thức đó, nó yêu cầu bạn viết nó từ đầu, tự xử lý bộ nhớ. Đó là bởi vì việc phân lớp một lớp lớp trực tiếp như vậy là giống như nói rằng bạn muốn cung cấp một triển khai mới cho các từ điển hoạt động như thế nào. Như tôi chắc chắn bạn có thể nói, đó là một nhiệm vụ quan trọng.

Giả sử bạn chắc chắn muốn phân lớp NSDictionary, đặt cược tốt nhất của bạn là viết phân lớp của bạn để chứa NSMutableDictionary bình thường làm thuộc tính và sử dụng để xử lý bộ nhớ của bạn. This tutorial cho bạn thấy một cách để thực hiện điều đó. Đó không phải là thực sự khó khăn, bạn chỉ cần vượt qua các phương pháp cần thiết thông qua tài sản từ điển của bạn.

Bạn cũng có thể thử sử dụng associative references, trong đó "mô phỏng việc thêm biến đối tượng vào một lớp hiện có". Bằng cách đó bạn có thể kết hợp một NSNumber với từ điển hiện có của bạn để đại diện cho thẻ, và không cần lớp con.

Tất nhiên, bạn cũng có thể chỉ có tag làm khóa trong từ điển và lưu trữ giá trị bên trong nó như bất kỳ khóa từ điển nào khác.

5

Từ https://stackoverflow.com/a/1191351/467588, đây là những gì tôi đã làm để tạo một lớp con của công việc NSDictionary. Tôi chỉ cần khai báo một NSDictionary như là một biến cá thể của lớp của tôi và thêm một số phương thức cần thiết khác. Nó được gọi là "Composite Object" - cảm ơn @mahboudz.

@interface MyCustomNSDictionary : NSDictionary { 
    NSDictionary *_dict; 
} 
@end 

@implementation MyCustomNSDictionary 
- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt { 
    _dict = [NSDictionary dictionaryWithObjects:objects forKeys:keys count:cnt]; 
    return self; 
} 
- (NSUInteger)count { 
    return [_dict count]; 
} 
- (id)objectForKey:(id)aKey { 
    return [_dict objectForKey:aKey]; 
} 
- (NSEnumerator *)keyEnumerator { 
    return [_dict keyEnumerator]; 
} 
@end 
+2

Bạn đang phân lớp và đóng gói ??? – Bgi

+0

Điều này tương tự như những gì Apple giới thiệu - một đối tượng hỗn hợp: https://developer.apple.com/library/mac/documentation/General/Conceptual/CocoaEncyclopedia/ClassClusters/ClassClusters.html#//apple_ref/doc/uid/ TP40010810-CH4-SW81 – mahboudz

+0

@Bgi yeah, loại. Đó là một cách tiếp cận được đề xuất bởi Apple gọi là "Composite Object". Xem liên kết trong câu trả lời của tôi. – Hlung

2

Tôi vừa thực hiện một mẹo nhỏ.
Tôi không chắc chắn rằng đó là giải pháp tốt nhất (hoặc thậm chí là tốt để làm điều đó).

@interface MyDictionary : NSDictionary 

@end 

@implementation MyDictionary 

+ (id) allocMyDictionary 
{ 
    return [[self alloc] init]; 
} 

- (id) init 
{ 
    self = (MyDictionary *)[[NSDictionary alloc] init]; 

    return self; 
} 

@end 

Điều này làm việc tốt cho tôi.

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