对于递归遍历未知结构的NSDictionary感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解递归遍历树,并且为您提供关于CFDictionary不会桥接到NSDictionary(Swif
对于递归遍历未知结构的NSDictionary感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解递归遍历树,并且为您提供关于CFDictionary不会桥接到NSDictionary(Swift 2.0 / iOS9)、cocoa – 有序的NSDictionary、Cocoa的NSDictionary:为什么复制密钥?、C有一个类似于Objective-C的NSDictionary字典吗?的宝贵知识。
本文目录一览:- 递归遍历未知结构的NSDictionary(递归遍历树)
- CFDictionary不会桥接到NSDictionary(Swift 2.0 / iOS9)
- cocoa – 有序的NSDictionary
- Cocoa的NSDictionary:为什么复制密钥?
- C有一个类似于Objective-C的NSDictionary字典吗?
递归遍历未知结构的NSDictionary(递归遍历树)
是否有人对未知结构的NSDictionary进行了递归有序遍历?我想学习任何NSDictionary,并按层次结构顺序处理每个级别。
1)此数据来自经过验证的JSON。可以肯定地说,从诸如SBJSON(JSON框架)之类的框架创建的NSDictionary仅会导致嵌套字典,数组和任意叶的组合吗?
2)如何使用适用于数组和字典的快速枚举完成泛型遍历?使用下面的代码,一旦我到达数组中的字典,它将停止遍历。但是,如果我继续在排列条件(以检查阵列内的字典)递归,它barfs上的下一个迭代idvalue = [dict valueForKey:key];
用-[__NSCFDictionary length]: unrecognizedselector sent to instance
SIGABRT。我不知道为什么会出现问题,因为我已经越过了顶层字典(找到了次级字典数组)。
-(void)processParsedObject:(id)dict counter:(int)i parent:(NSString *)parent{ for (id key in dict) { id value = [dict valueForKey:key]; NSLog(@"%i : %@ : %@ -> %@", i, [value class], parent, key); if ([value isKindOfClass:[NSDictionary class]]) { i++; NSDictionary* newDict = (NSDictionary*)value; [self processParsedObject:newDict counter:i parent:(NSString*)key]; i--; } else if ([value isKindOfClass:[NSArray class]]) { for (id obj in value) { NSLog(@"Obj Type: %@", [obj class]); } } }}
非常感谢
答案1
小编典典我做过类似的事情,将遍历来自Web服务的JSON结构化对象并将每个元素转换为可变版本。
- (void)processParsedObject:(id)object{ [self processParsedObject:object depth:0 parent:nil];}- (void)processParsedObject:(id)object depth:(int)depth parent:(id)parent{ if ([object isKindOfClass:[NSDictionary class]]) { for (NSString* key in [object allKeys]) { id child = [object objectForKey:key]; [self processParsedObject:child depth:(depth + 1) parent:object]; } } else if ([object isKindOfClass:[NSArray class]]) { for (id child in object) { [self processParsedObject:child depth:(depth + 1) parent:object]; } } else { // This object is not a container you might be interested in it''s value NSLog(@"Node: %@ depth: %d", [object description], depth); }}
CFDictionary不会桥接到NSDictionary(Swift 2.0 / iOS9)
func optionalProblemDictionary() -> CFDictionary? { let key = "key" let value = "value" var keyCallBacks = CFDictionaryKeyCallBacks() var valueCallBacks = CFDictionaryValueCallBacks() let cfDictionary = CFDictionaryCreate(kcfAllocatorDefault,UnsafeMutablePointer(unsafeAddressOf(key)),UnsafeMutablePointer(unsafeAddressOf(value)),1,&keyCallBacks,&valueCallBacks) return cfDictionary }
相当简单(有点傻)但它的功能返回和可选的CFDictionary.尝试从此函数创建NSDictionary时,“fun”开始:
以下为什么不工作?
if let problemDictionary = optionalProblemDictionary() as? NSDictionary { print(problemDictionary) // never enters,no warnings,compiles just fine }
虽然这很好吗?
if let cfDictionary = optionalProblemDictionary() { let problemDictionary = cfDictionary as NSDictionary print(problemDictionary) }
XCode 7.0(7A220)
解决方法
CFDictionary?并且不能强制转换为(非可选)
的NSDictionary.
这是一个更简单的示例,演示了与CFString和Nsstring相同的问题:
let cfString = "foobar" as CFString? if let s1 = cfString as? Nsstring { print("s1 = \(s1)") // not executed }
(问题仍然是为什么这不会给编译器错误或
至少编译器警告,因为这个可选的强制转换可以
永远不会成功.)
但是对可选的Nsstring进行转换?作品:
if let s2 = cfString as Nsstring? { print("s2 = \(s2)") // prints "s2 = foobar" }
在您的情况下,如果您将“有问题的案例”更改为
if let problemDictionary = cfDict as NSDictionary? { print(problemDictionary) }
然后执行if-block.
请注意,在Swift中构建CFDictionary的方法不正确
并在我的测试中实际导致程序崩溃.一个原因是
字典回调设置为空结构.
另一个问题是unsafeAddressOf(key)桥接了Swift
字符串到Nsstring,可以立即解除分配.
我不知道在Swift中构建CFDictionary的最佳方法是什么,
但这在我的测试中起作用:
func optionalProblemDictionary() -> CFDictionary? { let key = "key" as Nsstring let value = "value" as Nsstring var keys = [ unsafeAddressOf(key) ] var values = [ unsafeAddressOf(value) ] var keyCallBacks = kcfTypeDictionaryKeyCallBacks var valueCallBacks = kcfTypeDictionaryValueCallBacks let cfDictionary = CFDictionaryCreate(kcfAllocatorDefault,&keys,&values,&valueCallBacks) return cfDictionary }
cocoa – 有序的NSDictionary
我意识到NSDictionary中没有特定的值顺序,但在我的情况下,我需要使用setValue保存我添加的顺序:forKey:,就像一个数组.
我怎么能这样做?
任何帮助赞赏.
解决方法
如果要按顺序存储,则应使用数组.
或者你必须使用一些复杂的方法,继续使用键附加一个int orderNumber(你需要在每个setobject / setValue之后增加它).存储和检索:
NSDictionary *dict=[NSDictionary new]; Nsstring *key=....; [dict setValue:@"some value" forKey:[Nsstring stringWithFormat:@"%d-%@",orderNumber,key]];
或者,您可以使用每个索引具有一个字典的数组.
另一种方法是使用自定义类
@interface .... @property(...) NSInteger index; @property(...) Nsstring *key; @property(...) id object; // and methods to retrieve based on key,based on index etc @end
编辑2:
发现非常类似于我一年前发布的内容,请参阅此OrderedDictionary.
Cocoa的NSDictionary:为什么复制密钥?
我经常想使用较重的物体作为键,只需将一个物体映射到另一个物体。当我这样做时,我真正的意思是:
[dictionary setobject:someObject forKey:[NSValue valueWithPointer:keyObject]];
(“当我回来,再次给你这个相同的关键对象实例,让我相同的价值。”)
…这正是我最终做的,有时会绕过这个设计。 (是的,我知道桌面Cocoa中的NSMapTable;但是iPhone不支持这一点。)
但是我真的不知道为什么复制密钥是必要的或首选的。它购买的是执行还是来电?
解决方法
NSMutableString* key = ... NSMutableDictionary* dict = [[NSMutableDictionary alloc] init]; [dict setobject: ... forKey: key];
我们假设字典没有复制密钥,而是保留它。如果现在,在稍后的一点,原始字符串被修改,那么很可能你不会再次在字典中找到你的存储值,即使你使用相同的键对象(即,以上示例中的要点)。
为了保护自己免受这样的错误,字典复制所有的键。
注意,btw,它很简单地定义-copyWithZone:只是做return [self retain]。这是允许的和良好的代码,如果你的对象是不可变的,NScopying的合同是专门设计的,所返回的对象必须是(sorta,kinda)不可变的:
Implement NScopying by retaining the original instead of creating a new copy when the class and its contents are immutable.
和
The copy returned is immutable if the consideration “immutable vs. mutable” applies to the receiving object; otherwise the exact nature of the copy is determined by the class.
(均为NSCopying Reference)
即使您的对象不是不可变的,如果您只使用基于身份的等同/哈希实现,即实现,也不会受到对象内部状态的任何影响,您可能会忽略该实现。
C有一个类似于Objective-C的NSDictionary字典吗?
解决方法
例如,要从整数映射到std :: string:
#include <map> #include <string> #include <iostream> int main() { std::map<int,std::string> my_map; my_map[3] = "hello"; my_map[4] = "world"; std::cout << my_map[3] << " " << my_map[4] << std::endl; return 0; }
我们今天的关于递归遍历未知结构的NSDictionary和递归遍历树的分享就到这里,谢谢您的阅读,如果想了解更多关于CFDictionary不会桥接到NSDictionary(Swift 2.0 / iOS9)、cocoa – 有序的NSDictionary、Cocoa的NSDictionary:为什么复制密钥?、C有一个类似于Objective-C的NSDictionary字典吗?的相关信息,可以在本站进行搜索。
本文标签: