Biến thành một vấn đề nhỏ thú vị. Tôi đã viết một phương pháp để lọc một mảng các đối tượng độc đáo:Chuyển đổi NSArray thành NSSet, các cá thể lớp tùy chỉnh chuyển không nhất quán
- (NSArray*)distinctObjectsByAddress {
NSSet* uniqueSet = [NSSet setWithArray:self];
NSArray* retArray = [uniqueSet allObjects];
return retArray;
}
và đã viết một bài kiểm tra đơn vị để kiểm tra:
- (void)testDistinctObjectsByAddress5 {
Person* adam1 = [[Person alloc] initWithFirstName:@"adam" lastName:@"adam" andParent:nil];
Person* adam2 = [[Person alloc] initWithFirstName:@"adam" lastName:@"adam" andParent:nil];
testPersonArray = [NSArray arrayWithObjects:adam1,adam2, nil];
NSArray* checkArray = [testPersonArray distinctObjectsByAddress];
STAssertEquals([checkArray count], [testPersonArray count], @"Array %@ counts should match %@ %@",checkArray,adam1,adam2);
}
Khá đơn giản. Phần thú vị là khoảng 80-90% thời gian thử nghiệm trôi qua và thường xuyên như vậy nó không thành công vì phương thức distinctObjectsByAddress
chỉ trả về một đối tượng. Tôi đã có thể theo dõi nó để gọi [NSSet setWithArray:self]
nhưng tôi cũng đã có thể xác minh rằng hai đối tượng người là hai đối tượng khác nhau (ít nhất là họ có địa chỉ khác nhau). Tôi giả định rằng setWithArray:
chỉ là làm một địa chỉ cơ bản so sánh nhưng tôi không hiểu tại sao nó đôi khi sản xuất hai đối tượng như nó nên và đôi khi sản xuất chỉ có một.
Điều tôi vừa thử đã thay đổi adam2
để tên và họ không chính xác giống như adam1
. Điều này dường như sửa lỗi. Liệu điểm này có phải là một số loại tối ưu hóa trình biên dịch khi các đối tượng hợp lý không?
Tôi đoán rằng vấn đề là với Người và cách nó triển khai các phương thức băm và bình đẳng mà NSSet sử dụng. –
Nó sẽ sử dụng 'isEqual:' như được định nghĩa bởi giao thức 'NSObject' để so sánh các đối tượng; bạn đã triển khai nó hay 'hash' trên' Person' chưa? – Tommy
Ngoài vấn đề băm, bạn không kiểm tra rõ ràng adam1 và adam2 cho nil. Nếu thỉnh thoảng không thành công, điều đó sẽ giải thích thất bại kiểm tra. – bneely