2012-02-28 24 views
5

Tôi có một lớp tùy chỉnh được gọi là card và tôi cần tạo một bộ 10 thẻ duy nhất từ ​​một mảng thẻ có kích thước ngẫu nhiên. Ngoài ra, tôi cần bao gồm bất kỳ thẻ được ghi trong danh sách trắng nào trước để đảm bảo chúng luôn được bao gồm.NSMutableSet chứa các bản sao

Vấn đề của tôi là thẻ từ danh sách cho phép (và chỉ có trong danh sách cho phép) có khả năng được sao chép trong bộ này. Các thẻ được thêm vào ngẫu nhiên không bao giờ bị trùng lặp và số đếm luôn chính xác (10). Tôi không thể tìm ra lý do tại sao isEqual dường như đôi khi hoạt động nhưng không phải lúc nào.

Đây là nơi tôi có thể tạo các thiết lập (randoms là mảng thẻ tiềm năng được chọn từ):

NSMutableSet *randomCards = [NSMutableSet setWithCapacity:10]; 

[randomCards addObjectsFromArray:whiteListArray]; 

while ([randomCards count] < 10) { 
    NSNumber *randomNumber = [NSNumber numberWithInt:(arc4random() % [randoms count])]; 
    [randomCards addObject:[randoms objectAtIndex:[randomNumber intValue]]]; 
} 

Tôi overrode phương pháp isEqual cho lớp card của tôi dựa trên một câu hỏi khác đã trả lời ở đây:

- (BOOL)isEqual:(id)other { 

if (other == self) 
    return YES; 
if (!other || ![other isKindOfClass:[self class]]) 
    return NO; 
return [self isEqualToCard:other]; 

} 

- (BOOL)isEqualToCard:(Card *)myCard { 

if (self == myCard) { 
    return YES; 
} 
if ([self cardName] != [myCard cardName] && ![(id)[self cardName] isEqual:[myCard cardName]]) 
    return NO; 

return YES; 
} 

Dường như nó hoạt động hoàn hảo trừ khi tôi thêm thẻ vào danh sách trắng, tôi không thể tìm ra cách tôi kết thúc với bản sao (nhưng không bao giờ nhiều hơn 2 bản sao).

Trả lời

15

Bạn cần ghi đè hash ngoài isEqual.

Thực tế, bạn luôn luôn cần đảm bảo hai phương thức này hoạt động cùng nhau. Từ Apple's documentation:

Nếu hai đối tượng bằng nhau (được xác định bằng phương pháp isEqual:), chúng phải có cùng giá trị băm. Điểm cuối cùng này đặc biệt quan trọng nếu bạn định nghĩa băm trong một lớp con và có ý định đặt các cá thể của phân lớp đó vào một tập hợp.

Something như thế này nên làm việc:

- (NSUInteger)hash { 
    return [[self cardName] hash]; 
} 

Bằng cách này băm của bạn phụ thuộc vào các thông tin tương tự mà bạn đang sử dụng để thực hiện so sánh.

Hàm băm được sử dụng bởi cấu trúc dữ liệu như NSMutableSet để nhóm nhanh các đối tượng vào các nhóm khác nhau. Điều quan trọng là nếu hai đối tượng bằng nhau, chúng có cùng giá trị băm. (Tuy nhiên, nếu hai đối tượng có cùng giá trị băm nhưng không bằng nhau. Vì vậy, bạn luôn có thể trả lại cùng một số từ hash, nhưng sau đó hiệu suất của bạn sẽ giống như sử dụng một mảng. Cấu trúc dữ liệu!)

+0

Ah Hoàn hảo, cảm ơn rất nhiều. Tôi đã dẫn tôi xuống con đường sai lầm bởi vì nó dường như làm việc đôi khi và không phải những người khác. – hokiewalrus

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