亲爱的:提前,谢谢您的时间。
最近,我决定学习Objective-C(我是一个很长时间的C-hacker),在阅读了Kochan的漂亮文本并深入研究Apple文档后,我仍然对实现递归的最佳方法感到困惑。 class(即一个ivar具有类型的类 同一类)。具体来说,我们假设我们希望实现二叉树类。首先,我们有一个基本的节点类,我将其简化为:
@interface MMNode : NSObject {
NSString *label;
}
现在我们可以用两种不同的方式实现我们的树。第一个(以及我认为更明显的方法)是将递归放在类本身中。
@interface MMTree : NSObject {
MMNode *root;
MMTree *leftTree;
MMTree *rightTree;
}
@property (nonatomic, copy) MMNode *root;
@property (nonatomic, retain) MMTree *leftTree;
@property (nonatomic, retain) MMTree *rightTree;
第二种方法,在精彩的CHDataStructures.framework中使用,实现了如下数据结构:
typedef struct MMTreeNode {
MMNode *node;
// union {
// struct {
struct MMTreeNode *leftTree;
struct MMTreeNode *rightTree;
// };
// };
} MMTreeNode;
@interface MMTreeStruct : NSObject {
MMTreeNode *root;
}
这里的解决方案更像是“指针 - riffic”,递归被推入 结构。 (如评论中所述,匿名结构和 工会不是必需的。但是,由于许多应用程序都需要 在每个节点的附加信息,我将按原样保留代码。
我已经实施了两种解决方案,但效果很好。前者似乎更直接,更“OO”;后者,更多“以C为中心”,具有稍微复杂的来源。
后一种技术是首选吗?如果是这样,客观原因是什么?所有我可以确定的可能是后者更友好,因为结构具有固定的大小。
再次感谢StackOverflow并感谢CocoaHeads。
更新:我应该添加,似乎是CoreFoundation对象CFTree 使用类似的结构实现。
答案 0 :(得分:4)
作为CHDataStructures.framework的作者,希望我能添加一点见解。 : - )
我的经验法则是使用对象,除非有明显的理由使用结构。
由于我正在实现低级数据结构,因此我选择使用结构而不是对象,主要是出于性能原因。对象不仅每个实例需要更多的内存,而且调用方法也有一些开销。如果对象仅具有声明为@public的实例变量,但仍需要alloc / init,并且Objective-C对象变量为零填充,而除非使用calloc()
,则结构不是。{/ p>
Objective-C对象对结构的一个优点是与垃圾收集(10.5+)自动集成,而原始C内存必须跳过几个环以获得相同的好处。我同意你对Cocoa开发人员更熟悉(也很明显)对象的内存管理。这就是我使用类作为接口和存储结构的原因。
注意:第二个代码示例中的匿名联合和结构对于这种特殊情况是无关紧要的。我只使用它们来编写更简化但可读的二进制搜索树算法。 (详情请见http://dysart.cs.byu.edu/CHDataStructures/struct_c_h_binary_tree_node.html)我对它们进行了评论,希望避免让随意的读者感到困惑,但仍留待将来参考。