2

我留下了原文,所以人们可以理解评论的上下文。希望这个例子能更好地帮助解释我所追求的。

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

例如,我在 NSNotificationCenter 上编写了一个method-sqizzling 类别,它会在解除分配时自动删除任何观察者。

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

WJH_NSNotification_WJHAutoRemoval__Private__BlockObserver

这是一口,目前我只是这样做......

#define BlockObserver WJH_NSNotification_WJHAutoRemoval__Private__BlockObserver

只需在代码中使用 BlockObserver。

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

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

对于纯 C,我会是“静态”,而对于 C++,我会是“命名空间 { }”

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

原始问题

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

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

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

@interface Helper : NSObject
...
@end

@implementation Helper : NSObject
...
@end

我什至在任何地方都找不到这方面的提示,而且我在接口/实现前面加上“静态”的微弱尝试都出现了错误。

谢谢!

4

2 回答 2

3

由于 Objective-C 运行时,我不相信你能够做你想做的事。您的所有类都加载到运行时中,并且具有相同名称的多个类将相互冲突。

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

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

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

于 2012-05-14T15:07:44.230 回答
0

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

但我不清楚你为什么需要这个。如果你有一个私有类WJHAutoRemovalHelper或其他什么,它似乎不太可能与其他任何人发生冲突,就像私有 Apple 类或私有 3rdparty 框架类发生冲突一样。没有理由不遗余力地让它变得晦涩难懂。前缀WJHAutoRemoval应该足够使它独一无二。您是否正在尝试解决一些更深层次的问题?

顺便说一句:你如何实施其余的?您是否正在对观察者进行 ISA-swizzling 以覆盖其 dealloc?这似乎有很多棘手的代码来使一个非常小的事情稍微方便一些。


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

但这是大量的工作和复杂性,没有任何好处。ObjC 不会像 C++ 那样花太多时间担心保护程序不受自身影响。它使用命名约定和编译器警告来告诉你什么时候做错了,并期望作为一个优秀的程序员你会避免做错事。

于 2012-05-14T20:47:00.770 回答