2009-07-14 43 views
10

Tôi muốn tạo một từ điển để tạo dữ liệu cho UITableView của mình một cách có lập trình nhưng tôi đang gặp khó khăn với nó. Tôi muốn tạo một từ điển tương tự như this property list (image) cho hoặc lấy một vài mục.Tạo danh sách thuộc tính từ điển theo lập trình

Tôi đã nhìn "Property List Programming Guide: Creating Property Lists Programmatically" và tôi đã đưa ra một mẫu nhỏ của riêng tôi:

//keys 

NSArray *Childs = [NSArray arrayWithObjects:@"testerbet", nil]; 
NSArray *Children = [NSArray arrayWithObjects:@"Children", nil]; 
NSArray *Keys = [NSArray arrayWithObjects:@"Rows", nil]; 
NSArray *Title = [NSArray arrayWithObjects:@"Title", nil]; 

//strings 

NSString *Titles = @"mmm training"; 

//dictionary 

NSDictionary *item1 = [NSDictionary dictionaryWithObject:Childs, Titles forKey:Children , Title]; 
NSDictionary *item2 = [NSDictionary dictionaryWithObject:Childs, Titles forKey:Children , Title]; 
NSDictionary *item3 = [NSDictionary dictionaryWithObject:Childs, Titles forKey:Children , Title]; 
NSArray *Rows = [NSArray arrayWithObjects: item1, item2, item3, nil]; 
NSDictionary *Root = [NSDictionary dictionaryWithObject:Rows forKey:Keys]; 

// NSDictionary *tempDict = [[NSDictionary alloc] //initWithContentsOfFile:DataPath]; 
NSDictionary *tempDict = [[NSDictionary alloc] initWithDictionary: Root]; 

Tôi đang cố gắng để sử dụng dữ liệu này của hệ thống phân cấp cho quan điểm bàn của tôi.

Vì vậy, tôi đã tự hỏi làm thế nào tôi có thể tạo danh sách tài sản của tôi (từ điển) lập trình để tôi có thể điền nó với mảng của riêng tôi.

Tôi vẫn còn mới với sự phát triển của iPhone nên chịu đựng với tôi. ;)

Trả lời

24

Đây là một tình huống mà "dạy một người đàn ông để câu cá" là một cách tiếp cận hữu ích hơn rất nhiều so với "cung cấp cho một người đàn ông một con cá". Một khi bạn hiểu các nguyên tắc cơ bản và API NSDictionary, nó trở nên dễ dàng hơn nhiều để tạo ra giải pháp tùy chỉnh của riêng bạn. Dưới đây là một vài quan sát và điểm học tập:

  • Phương pháp +dictionaryWithObject:forKey: được sử dụng để tạo ra một NSDictionary với một cặp khóa-giá trị duy nhất. Nó sẽ không chấp nhận các đối số được phân cách bằng dấu phẩy sau mỗi dấu hai chấm (:) trong cuộc gọi phương thức, chỉ một. Để tạo một từ điển với nhiều cặp khóa-giá trị, sử dụng một trong 2 phương thức có liên quan: +dictionaryWithObjects:forKeys: chấp nhận hai đối tượng NSArray chứa các giá trị và khóa hoặc +dictionaryWithObjectsAndKeys: thay thế (đối tượng, khóa, đối tượng, khóa) với đối số chấm dứt nil.
  • Đơn giản hóa mã tạo. Bạn không cần một triệu biến địa phương chỉ để tạo ra điều. Sử dụng các đối số nội tuyến nơi nó có ý nghĩa. Một cách để thực hiện việc này để xây dựng từ điển của bạn bằng mã là , sau đó (nếu cần) hãy tạo một bản sao bất biến của nó bằng cách gọi -copy trên đó. (Hãy nhớ rằng một phương thức sao chép trả về một đối tượng mới mà bạn phải giải phóng để tránh rò rỉ bộ nhớ.) Bằng cách đó bạn không cần phải có một biến cho mỗi giá trị duy nhất để bạn có thể tạo một cấu trúc "một lần") ở mỗi cấp độ.
  • Sử dụng +arrayWithObject: để tạo NSArray với một đối tượng duy nhất.
  • (Đề xuất kiểu) Không bao giờ sử dụng chữ hoa để bắt đầu tên biến, phương pháp hoặc hàm. (Lưu ý rằng SO làm nổi bật các biến hàng đầu như các tên lớp.) Nó chắc chắn sẽ giúp những người khác đọc mã của bạn khỏi bị nhầm lẫn về ý định của bạn bằng cách đặt tên lược đồ của bạn.

Chỉ cần để cung cấp cho bạn một hương vị của những gì tạo từ điển trong các hình ảnh liên quan có thể trông như trong mã ... (tôi bỏ qua tên biến của bạn lựa chọn và sử dụng cả hai phương pháp khác nhau cho đầy đủ.)

NSDictionary *item1 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"Screen J",[NSNumber numberWithInt:3],nil] 
                forKeys:[NSArray arrayWithObjects:@"Title",@"View",nil]]; 
NSDictionary *item2 = [NSDictionary dictionaryWithObjectsAndKeys: 
             @"Screen I", @"Title", 
             [NSArray arrayWithObject:item1], @"Children", 
             nil]; 
... 
0
NSMutableDictionary *topLevel = [NSMutableDictionary dictionary]; 

NSMutableDictionary *item1 = [NSMutableDictionary dictionary]; 
NSString *item1title = [NSString stringWithString:@"Title 1"]; 
NSMutableDictionary *item1children = [NSMutableDictionary dictionary]; 

// create children 
NSString *item1child1 = [NSString stringWithString:@"item 1, child 1"]; 

NSMutableDictionary *item1child2 = [NSMutableDictionary dictionary]; 
NSString *item1child2title = [NSString stringWithString:@"Title 1-2"]; 
NSMutableDictionary *item1child2children = [NSMutableDictionary dictionary]; 

NSString *item1child2child1 = [NSString stringWithString:@"item 1, child 2, child 1"]; 
NSString *item1child2child2 = [NSString stringWithString:@"item 1, child 2, child 2"]; 

[item1child2 setObject:item1child2title forKey:@"Title"]; 
[item1child2children setObject:item1child2child1 forKey:@"item 1 child2 child 1"]; 
[item1child2children setObject:item1child2child2 forKey:@"item 1 child2 child 2"]; 

[item1child2 setObject:item1child2children forKey:@"children"]; 

// add children to dictionary 
[item1children setObject:item1child1 forKey:@"item1 child1"]; 
[item1children setObject:item1child2 forKey:@"item1 child2"]; 

// add to item 1 dict 
[item1 setObject:item1title forKey:@"Title"]; 
[item1 setObject:item1children forKey:@"children"]; 

NSMutableDictionary *item2 = [NSMutableDictionary dictionary]; 
NSString *item2title  = [NSString stringWithString:@"Title"]; 
NSMutableDictionary *item2children = [NSMutableDictionary dictionary]; 

NSString *item2child1 = [NSString stringWithString:@"item 2, child 1"]; 
NSString *item2child2 = [NSString stringWithString:@"item 2, child 2"]; 
NSString *item2child3 = [NSString stringWithString:@"item 2, child 3"]; 

// add children to dictionary 
[item2children setObject:item2child1 forKey:@"item2 child1"]; 
[item2children setObject:item2child2 forKey:@"item2 child2"]; 
[item2children setObject:item2child3 forKey:@"item2 child3"]; 

// add to item 2 dict 
[item2 setObject:item2title forKey:@"Title"]; 
[item2 setObject:item2children forKey:@"children"]; 

[topLevel setObject:item1 forKey:@"Item 1"]; 
[topLevel setObject:item2 forKey:@"Item 2"]; 
+0

cảm ơn người đàn ông! ... Tôi sẽ kiểm tra nó và cố gắng chơi với nó một chút nếu tôi nhận được những điều này từ điển đúng;) Tôi cũng nhận thấy bạn đã không sử dụng bất kỳ mảng (tôi thấy trẻ em ví dụ trong liên kết hình ảnh và các ứng dụng mẫu), tôi hy vọng nó vẫn hoạt động;) ngay cả khi nó không bạn có lòng biết ơn của tôi. một lần nữa thnx .. –

0

đầu tiên của .. siêu! cảm ơn .. Tôi thực sự đánh giá cao sự giải thích và đoạn mã. Vì bạn đã cho tôi một lời giải thích tốt như vậy, tôi hy vọng bạn không nhớ tôi hỏi thêm một vài câu hỏi nữa.

Trước tiên, tôi đã làm như bạn đề xuất và đây là những gì tôi đã đưa ra: (Tôi đã sử dụng danh sách sản phẩm gốc của tôi thay vì ví dụ lần này vì vậy đây là nơi bảng khoan xuống lấy (hoặc cần lấy) cấu trúc cây).

http://img509.imageshack.us/img509/7523/picture2lsg.png

NSDictionary *root = [NSMutableDictionary dictionary]; 
NSDictionary *item1 = [NSDictionary dictionaryWithObject:[NSArray arrayWithObject:@"VirtuaGym Online"] forKey:[NSArray arrayWithObjects:@"Title"]]; 
NSDictionary *item2 = [NSDictionary dictionaryWithObject:[NSArray arrayWithObject:@"Do the training"] forKey:[NSArray arrayWithObjects:@"Title"]]; 
NSDictionary *item3 = ... 

[root setObject:item1 forKey:@"Item 1"]; 
[root setObject:item2 forKey:@"Item 2"]; 

Cũng đã làm một số nghiên cứu và thử một cái gì đó khác với một số đầu vào khác ..

NSMutableArray *Rows = [NSMutableArray arrayWithCapacity: 1]; 

for (int i = 0; i < 4; ++i) { 
    NSMutableArray *theChildren = [NSMutableArray arrayWithCapacity: 1]; 
    [theChildren addObject: [NSString stringWithFormat: @"tester %d", i]]; 
NSString *aTitle = [NSString stringWithFormat: @"Item %d", i]; 
    NSDictionary *anItem = [NSDictionary dictionaryWithObjectsAndKeys: aTitle, @"Title", theChildren, @"Children"]; 
    [Rows addObject: anItem]; 
} 

NSDictionary *Root = [NSDictionary withObject: Rows andKey: @"Rows"]; 

tôi quyết định chỉ kiểm tra cả hai tuy nhiên nó làm những gì tôi muốn. Nó cho tôi một lỗi EXC_BAD_ACCESS.

Tôi cũng đã tự hỏi vì tôi thấy bạn sử dụng số trong đoạn mã của bạn, có thể bạn không còn sử dụng NSString vì đó là những gì các plist sử dụng .. có thể là hoàn toàn khỏi đây tất nhiên

NSDictionary *item1 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"Screen J",[NSNumber numberWithInt:3],nil] 
                forKeys:[NSArray arrayWithObjects:@"Title",@"View",nil]]; 

và thứ ba một câu hỏi là về cách tiếp cận có thể có của tôi đối với ứng dụng của tôi. Tôi có một trình phân tích cú pháp xml để lưu một số thông tin nhất định trong các mảng khác nhau. Tôi muốn sử dụng thông tin này cho bản tin UITableviews của tôi (infoFirstScreen [] infoSecondScreen [] infoThirdScreen []). Thông tin được cung cấp phải được kết nối như cây tôi đã cho bạn thấy ở trên. Đây là lý do tôi muốn xây dựng từ điển trong mã để tôi có thể lấy thông tin từ mảng của tôi và chèn nó ở đây. Câu hỏi của tôi là bạn nghĩ rằng cách tiếp cận của tôi là chính xác, sai hay có cách nào nhanh hơn?

một lần nữa thực sự đánh giá cao sự giải thích;)

+0

Nếu bạn đang cố gắng đặt một câu hỏi riêng, tốt hơn nên đăng câu hỏi mới để câu hỏi này có được khả năng hiển thị và câu trả lời. –

2

Tôi không chắc tôi hiểu mục tiêu cơ bản ở đây.

Dường như thời gian chạy, bạn đang xây dựng một từ điển sâu với nhiều nút con. Nhưng bạn đang xây dựng tất cả điều này với mã tĩnh ... tại sao bạn có thể không chỉ đơn giản là làm cho một plist (như một trong những bạn đã có một hình ảnh của) và đọc mà vào một NSDictionary? Cả NSDictionary và NSArray đều có các phương thức cho phép bạn chỉ cần đọc trong một tệp và nhận được một đối tượng được điền đầy đủ. Sau đó, nó dễ dàng hơn để chỉnh sửa và hiểu. Phương thức đó là dictionaryWithContentsOfFile.

Nếu tất cả dữ liệu thực sự được tạo trong thời gian chạy trước khi được đưa vào từ điển, thì có vẻ như bạn muốn có một kiểu mã đệ quy, khác với các ví dụ phẳng.

Cuối cùng, cá nhân tôi không thích phương thức dictionaryWithObjects:forKeys: trong NSDictionary để tạo từ điển. Nếu bạn phải làm những điều theo cách đó, tôi rất thích phương pháp thay thế dictionaryWithObjectsAndKeys: làm điều tương tự nhưng giữ chìa khóa với các đối tượng:

NSDictionary *item1 = [NSDictionary dictionaryWithObjectsAndKeys: 
         @"Screen J", 
         @"Title", 
         [NSNumber numberWithInt:3], 
         @"View"]; 
+1

Tôi muốn kiểm tra nếu tôi có thể kéo nó ra để nói chuyện để sau này tôi có thể cố gắng làm cho nó thực sự đệ quy và năng động hơn một chút như thế này for (int i = 0; i < 4; ++i) { NSMutableArray *theChildren = [NSMutableArray arrayWithCapacity: 1]; [theChildren addObject: [NSString stringWithFormat: @"tester %d", i]]; NSString *aTitle = [NSString Bạn có thể thấy mã "hoàn chỉnh" bên dưới. Thực tế mục tiêu thực sự của tôi là mang tính năng năng động hơn. Tôi đang cố gắng làm ít nhất từ ​​điển để làm việc để tôi có thể bắt đầu tạo ra động lực đó. Thnx cuối cùng nhưng không kém phần quan trọng đối với bạn –

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