Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 递归类设计模式:选项和最佳实践_Objective C_Design Patterns_Recursion_Class Design - Fatal编程技术网

Objective c 递归类设计模式:选项和最佳实践

Objective c 递归类设计模式:选项和最佳实践,objective-c,design-patterns,recursion,class-design,Objective C,Design Patterns,Recursion,Class Design,亲爱的所有人:提前,谢谢你的时间 最近,我决定学习Objective-C(我是一名长期的C-hacker),在阅读了Kochan的漂亮文本并深入苹果文档之后,我仍然对实现递归类(即ivar具有 同一类)。具体来说,假设我们希望实现一个二叉树类。首先,我们有一个基本的节点类,我将其简化为: @interface MMNode : NSObject { NSString *label; } 现在我们可以用两种不同的方式实现我们的树。第一个(我认为更明显的方法)是将递归放在类本身中。 @i

亲爱的所有人:提前,谢谢你的时间

最近,我决定学习Objective-C(我是一名长期的C-hacker),在阅读了Kochan的漂亮文本并深入苹果文档之后,我仍然对实现递归类(即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;

第二种方法(在wonderful中使用)实现此数据结构,如下所示:

typedef struct MMTreeNode {
    MMNode *node;
//  union { 
//      struct { 
            struct MMTreeNode *leftTree;
            struct MMTreeNode *rightTree;
//      };
//  };
} MMTreeNode;


@interface MMTreeStruct : NSObject {
    MMTreeNode *root;
}
这里的解决方案更为“指针riffic”,将递归推入 结构。(如评论中所述,匿名结构和 工会不是必需的。但是,由于许多申请都需要 在每个节点的附加信息中,我将保持代码不变)


我已经实现了这两种解决方案,它们都很好地工作。前者似乎更直截了当,更“OO”;后者,更为“以C为中心”,来源稍为复杂

后一种技术是首选的吗?如果是,客观原因是什么?我所能确定的是,由于结构具有固定的大小,后者可能对内存更友好

再一次,谢谢你们,谢谢你们这些笨蛋

更新:我应该添加,似乎CoreFoundation对象
使用类似的结构实现。

作为CHDataStructures.framework的作者,希望我能添加一些见解。:-)

我的经验法则是使用对象,除非有明显的理由使用结构

由于我正在实现低级数据结构,我选择使用结构而不是对象,主要是出于性能原因。对象不仅需要每个实例多一点内存,而且调用方法也有一些开销。如果对象只有声明为@public的实例变量,但您仍然必须alloc/init,并且Objective-C对象变量是零填充的,而结构不是零填充的,除非您使用
calloc()

Objective-C对象相对于structs的一个优势是与垃圾收集(10.5+)的自动集成,而原始C内存必须跳过几个环才能获得相同的好处。我同意您的观点,使用对象进行内存管理对于Cocoa开发人员来说更为熟悉(也更为明显)。这就是为什么我使用类作为接口,使用结构作为存储


注意:第二个代码示例中的匿名联合和结构与此特定情况无关。我使用它们只是为了编写更精简、可读性更强的二进制搜索树算法。(详情见)我对它们进行了评论,希望能避免让普通读者感到困惑,但它们仍留作将来参考。

谢谢。我希望你能看到这个…;-)我应该把上面的代码简化一些。最初,我在结构中有更多的信息用于额外的计算。你有这个开销的硬数字吗?我100%相信它的存在,但我很好奇,如果将这种类型的类作为iPhone应用程序的核心部分,我是否可以接受它。另外,为了验证我对Obj-C理论的理解:“retain”是否是非GC应用程序的正确@property声明(与assign相反)?我不想让leftTree在其他地方发布和发布,对吗?一位朋友向我指出了这篇文章。:-)我没有任何硬性数字。为
isa
指针的每个对象计划额外的4字节存储空间(32位)。函数调用需要比字段访问多一两条指令,动态方法调度增加了更多指令,但我还没有运行任何具体的测试。无论如何,这两种方法都应该足以在iPhone应用程序中使用。然而,对于真正繁重的用例,使用结构开始变得更有意义,特别是因为您不必担心iPhone上结构和GC的复杂性。:-)你是对的,在很多情况下,一个物体可以从你下面释放出来。对于属性,“retain”在GC和retain释放模式下都是正确的。(在许多情况下,“复制”更可取,但可能不适用于分层数据结构。)要分配原始内存,请使用NSAllocateCollectable和size和NSScannedOption,以便GC知道扫描该内存以查找其他GC管理的指针;同样重要的是,对GC管理的结构指针变量使用_strong属性,以便它们保持根目录,并且GC不会过早地收集它们。:-)谢谢,谢谢,谢谢。同样,使用CHDataStructures.CFTree的伟大工作不需要是二进制的。您可以在这里查看源代码。很抱歉在这里问这个问题,有人能告诉我这个CFTree有什么用途吗?使用NSDictionary和NSArray无法做到这一点