2011-01-14 39 views
19

Có lý do nào để NSDictionary trả lại khóa của nó là NSArray thay vì NSSet không? Tài liệu đã tuyên bố rằng thứ tự của các khóa trong mảng là không xác định, nó sẽ hợp lý để sử dụng một tập hợp.Tại sao [NSDictionary allKeys] không trả lại một tập hợp?

+4

Thú vị câu hỏi. Phải tự hỏi nếu nó hoàn toàn là vì NSArray đã ở quanh trước khi NSSet là trong những ngày của NeXTSTEP yore, nhưng đó là suy đoán hoàn toàn về phía tôi. –

+0

Câu hỏi hay, và tôi cũng giả định nó vì NSArray là xung quanh đầu tiên và là một cấu trúc được sử dụng rộng rãi hơn/hiểu/được biết đến nhiều hơn một tập hợp. Tôi không nhớ, nhưng có lẽ khi bạn trả về các mảng khóa, nó sắp xếp chúng, cung cấp một cách dễ dàng hơn để lặp qua? –

+0

[Gửi yêu cầu nâng cao.] (Http://bugreporter.apple.com/) –

Trả lời

2

Bộ có xu hướng bị bỏ qua một chút trong thiết kế API. Chúng sẽ được bao gồm hầu hết thời gian, nhưng thường dài sau tất cả các cấu trúc dữ liệu chuẩn khác. Thêm vào đó, bên cạnh NSFastEnumeration gần đây, không có bộ sưu tập chung hoặc giao thức chuỗi trong Objective-C - mọi lớp sưu tập hoàn toàn độc lập với tất cả các lớp khác - và nó trở nên rất khó chuyển sang các bộ sau một API đã được viết để trả về mảng.

+3

* ho * 'NSEnumerator' đã xuất hiện từ ít nhất là 10.0 –

+1

@Mike Abdullah: Lớp học đã tồn tại trong một thời gian dài. Một cách nhất quán để * nhận * một từ một bộ sưu tập tùy tiện giúp chúng tôi thậm chí cho đến ngày nay. Và thậm chí điều đó cũng không cung cấp nhiều chức năng hơn đếm nhanh. – Chuck

+1

'-objectEnumerator' có vẻ khá phù hợp với tôi. –

1

My đoán là Apple đang sử dụng NSArray khắp nơi (và hầu hết các lập trình viên), vì vậy sự lựa chọn này đến tự nhiên - và thay đổi ngay bây giờ sẽ có chi phí cao. Và nếu sử dụng mảng nội bộ, một bản sao của một mảng không thay đổi rẻ hơn nhiều so với việc xây dựng một bộ chỉ vì lợi ích của sự sang trọng toán học.

Cũng lưu ý rằng NSSetNSArray không có cha mẹ thường (tốt, ngoại trừ NSObject, tất nhiên), do đó trừu tượng hóa giao diện này cũng là bất khả thi (trừ trở về một cái gì đó phù hợp với NSFastEnumeration).

Chỉ cần đầu cơ hoang dã, tất nhiên. ;-)

+0

Tôi không nhiều về sự sang trọng toán học. Tôi gặp vấn đề trong một bài kiểm tra mà tôi muốn làm một cái gì đó như '[[dict allKeys] isEqual: expectedOutput]' và nhận ra rằng tôi sẽ phải loại bỏ thứ tự quan trọng mà lẽ ra không nên có ở nơi đầu tiên . – zoul

+0

Bạn nhận được bộ đó từ bạn so sánh với đâu? Chỉ cần tò mò ... – Eiko

+0

Tôi đang kiểm tra một số mã phát hiện các thuộc tính lớp và trả về chúng dưới dạng từ điển, các khóa là tên thuộc tính và các giá trị thuộc tính thuộc tính. Thử nghiệm đặc biệt này muốn biết liệu máy phân tích có phát hiện tất cả các thuộc tính và lấy tên của chúng đúng không, do đó 'expectedOutput' giống như' [NSSet setWithObjects: @ "foo", @ "bar", nil] '. Hoặc sẽ là, nếu từ điển trả lại các phím như một bộ. – zoul

0

tôi đoán là, kể từ -allKeys trả về một bản sao trong những chìa khóa (nó không được hỗ trợ bởi các từ điển) mà tạo ra một NSSet là rất nhiều chi phí (xây dựng một cây hoặc băm bảng hoặc bất cứ điều gì) khi so với chỉ đổ các khóa vào một mảng phẳng.

+0

Không theo tài liệu. '-allKeys' không ** không ** trả về một bản sao của các khóa. Nó trả về các khóa mà từ điển thực sự đang sử dụng. Nhầm lẫn có thể phát sinh vì * thiết lập * một khóa sẽ sao chép khóa đó. –

+0

Hãy để tôi làm rõ: nó không tự sao chép các khóa, nhưng nó trả về một bộ sưu tập các khóa trùng lặp với bộ sưu tập có trong từ điển. Tức là, các con trỏ * tới các đối tượng chính được sao chép sang mảng. –

-3

sử dụng sử dụng C++, std :: map cung cấp quyền truy cập vào các khóa của nó làm bộ. tập hợp được trả về thậm chí là "trực tiếp", tập hợp này phản ánh tập hợp các phím hiện tại đang diễn ra. tất nhiên bạn cũng được tự do tạo một bản sao.

+0

Làm thế nào mà thậm chí từ xa trả lời câu hỏi? – HAS

+0

Không chỉ không trả lời được câu hỏi mà còn không chính xác. –

0

Thông thường, bạn sẽ muốn làm điều gì đó với các phím, trong trường hợp này nó là đơn giản để sử dụng phương pháp NSDictionary này:

- (NSSet<KeyType> *)keysOfEntriesPassingTest:(BOOL (^)(KeyType key, ObjectType obj, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0); 

này giúp tiết kiệm thời gian bởi vì bây giờ bạn không cần phải lọc mảng bằng cách sử dụng một vị ngữ, bạn chỉ có thể thực hiện kiểm tra của bạn ở đây và bạn có được một thiết lập trở lại. Đơn giản.

Hơn nữa, bạn có thể tận dụng đa xử lý đồng thời bằng cách thông qua các tùy chọn liệt kê đồng thời phiên bản này của phương pháp này:

- (NSSet<KeyType> *)keysOfEntriesWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (^)(KeyType key, ObjectType obj, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0); 
Các vấn đề liên quan