gpt4 book ai didi

objective-c - cocoa 框架可以在其公共(public)头文件中隐藏 ivar 声明吗?

转载 作者:搜寻专家 更新时间:2023-10-30 20:04:09 25 4
gpt4 key购买 nike

这可能吗?

我的同事告诉我,像 apple 那样用前缀下划线命名 ivar 可能会导致一些问题。他说apple可以在一个class里声明一个ivar,不让在public头文件里。因此,如果我不小心命名了一个与不在头文件中的“ secret ivar”发生冲突的 ivar,这将导致问题。

我不太了解框架的工作原理,所以我不确定他的解释。我知道苹果只在代码指南中为方法名称保留使用前缀下划线,许多人在命名 ivar 时确实使用前缀下划线,他们说这是完全安全的,因为如果名称发生冲突,编译器会产生错误。如果 ivar 的名称在头文件中,我知道这是真的。但是那种不在公共(public)头文件中的“ secret ivar”呢?

我同事的另一个证据是,如果你转储苹果的应用程序框架的头文件并将其与苹果的公共(public)头文件进行比较,你会发现它们在方法和 ivars 的许多声明上都不匹配。

我对这个问题真的很困惑,希望有人能提供一些专业的答案,如果你能提供一些关于这个问题的可靠引用,那将是很大的帮助。

(我不知道我的问题解释的够不够清楚...请原谅我糟糕的英文...)

最佳答案

您的同事可能指的是类扩展中的实例变量。它们不会出现在类的(公共(public))界面中。例如,

// SomeClass.h -- this is a publicly distributed file
@interface SomeClass : NSObject
@end

// SomeClass.m -- this is known only to the framework developer
@interface SomeClass() {
NSString *someIvar;
}
@end

@implementation SomeClass
- (id)init {
self = [super init];
if (self) someIvar = @"Default";
return self;
}
@end

请注意,仅有权访问公共(public) header 的人不会通过读取声明该类的 header 文件知道 SomeClass 有一个名为 someIvar 的实例变量。此外,不可能像访问在公共(public)接口(interface)中声明的实例变量那样访问该实例变量。事实上,如果开发人员将 SomeClass 子类化并声明一个名为 someIvar 的实例变量,则不会发生名称冲突。例如,这是有效的:

// SomeSubclass.h
@interface SomeSubclass : SomeClass {
NSString *someIvar;
}
@end

在这种情况下,在 SomeSubclass 的实现中对 someIvar 的任何引用都将仅引用在 SomeSubclass 中声明的实例变量,而这实例变量不同于 SomeClass 的(私有(private))类扩展中声明的实例变量。

编译器为它们发出不同的符号名称:

  • _OBJC_IVAR_$_SomeClass.someIvar
  • _OBJC_IVAR_$_SomeSubclass.someIvar

并且,在实例化类型为 SomeSubclass 的对象时,两个实例变量位于不同的内存地址。

虽然对二进制文件的检查可能会显示 SomeClass 有一个名为 someIvar 的实例变量,即使它没有列在公共(public)头文件中,也不会有子类中的名称冲突。


也就是说,Apple 可能有一组与 SDK 一起分发的公共(public)头文件,但使用替代的私有(private)头文件来声明额外的实例变量。我发现这不太可能,如果真的发生的话,可能存在二进制不兼容的可能性。我想只有 Apple 能够提供明确的答案。

关于objective-c - cocoa 框架可以在其公共(public)头文件中隐藏 ivar 声明吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5629611/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com