如何在objective-c中创建文件范围类?

时间:2012-05-14 14:58:29

标签: objective-c

我离开了原版,所以人们可以理解评论的背景。希望这个例子能更好地帮助解释我的目标。

我可以在Obj-C中创建一个具有文件范围可见性的类吗?

例如,我在NSNotificationCenter上编写了一个方法方块类别,它会在deallocs时自动删除任何观察者。

我在实现中使用了一个帮助器类,为了防止名称冲突,我设计了一个命名方案。该类别是NSNotificationCenter(WJHAutoRemoval),因此此代码中使用的私有帮助程序类被命名为...

WJH_NSNotification_WJHAutoRemoval__Private__BlockObserver

那是满口的,目前我只是这样做......

#define BlockObserver WJH_NSNotification_WJHAutoRemoval__Private__BlockObserver

并在代码中使用BlockObserver。

但是,我不喜欢这个解决方案。

我想告诉编译器,“嘿,这个类名为Bar。我的代码将作为Bar访问它,但我真的是唯一需要知道的。自己生成一个时髦的名字,或者更好,甚至不输出符号,因为我是唯一应该关心的人。“

对于普通的C,我会“静态”而对于C ++“namespace {}”

在Obj-C中执行此操作的首选/最佳/唯一方法是什么?

原始问题

我想在另一个实现中使用一个帮助器类。但是,我不想要外部联系。现在,我只是让助手类名称非常独特,所以我不会得到重复的链接符号。

我可以使用静态C函数,但我想编写一个辅助类,只在编译单元内部具有链接器可见性。

例如,我想在多个.m文件中使用以下内容,每个“Helper”对该文件都是唯一的,并且没有其他编译单元具有链接器访问权限。如果我在10个不同的文件中有这个,我将有10个单独的类。

@interface Helper : NSObject
...
@end

@implementation Helper : NSObject
...
@end

我无法在任何地方找到任何暗示,而我在界面/实现中加上“静态”的微弱尝试都是错误的。

谢谢!

2 个答案:

答案 0 :(得分:3)

我不相信你会因为Objective-C Runtime而能够做你想做的事。所有类都加载到运行时,具有相同名称的多个类将相互冲突。

Objective-C是一种动态语言。与在编译时绑定方法调用的其他语言不同,Objective-C在调用(每次调用)时执行方法解析。运行时在运行时中找到该类,然后在类中查找该方法。运行时不能支持具有相同名称的不同类,而Objective-C不支持命名空间来分隔您的类。

如果你的Helper类在每种情况下都不同,那么它们将需要不同的类名(多个具有相同名称的类对我来说听起来不错,在任何语言中)。如果它们是相同的,那么为什么要单独声明它们呢?

我认为你需要重新考虑你的策略,因为你要做的事情听起来不是Objective-C或Cocoa。

答案 1 :(得分:0)

没有办法让课程“隐藏”。正如mttrb所说,类可以通过运行时通过名称访问。这与C和C ++不同,其中class只是链接器解析为地址的符号。每个类都被注入到类层次结构中。

但我还不清楚为什么你还需要这个。如果您有私有类WJHAutoRemovalHelper或其他任何内容,那么除了私有Apple类或私有第三方框架类之外,似乎不太可能与其他任何人发生冲突。没有理由采取英雄的长度来使其模糊不清;用WJHAutoRemoval作为前缀应该足以让它独一无二。你正试图解决一些更深层次的问题吗?

顺便说一下BTW:你是如何实现其余的?你是不是在调查观察者以超越它的dealloc?这似乎是一个很棘手的代码,使一个非常小的东西稍微方便。


关于“私人”课程的问题,如果你手工完成,你所建议的是可能的,但实际上没有理由。您可以生成一个随机的唯一类名,在其上调用objc_allocateClassPair()objc_registerClassPair,然后在运行时将其分配给Class变量。 (然后调用class_addMethodclass_addIvar来构建它。然后您可以在需要时随时通过该变量引用它。当然,在运行时通过调用objc_getClassList仍可访问它,但是系统中的类名不会有符号。

但这是很多工作和复杂性,没有任何好处。 ObjC并没有花太多时间担心像C ++那样保护程序。它使用命名约定和编译器警告来告诉您何时出错,并期望作为一名优秀的程序员,您将避免做错事。