【问题标题】:Is there any way to add an iVar that's not in the header file (not using LLVM 2.0 or later) in Objective-C?有没有办法在 Objective-C 中添加不在头文件中的 iVar(不使用 LLVM 2.0 或更高版本)?
【发布时间】:2011-04-12 17:32:09
【问题描述】:

我最近了解到您可以使用 LLVM2.0 在类扩展中添加 ivar。 (gcc 不能这样做) 这在某种程度上是真正私有的 iVar,因为其他用户不存在它,因为它不在头文件中。 喜欢:

//SomeClass.h
@interface SomeClass : NSObject {

}
@end

//SomeClass.m
@interface SomeClass ()
{
    NSString *reallyPrivateString;
}
@end

@implementation SomeClass

@end

但这确实依赖于编译器。有没有其他方法可以声明一个不在头文件中的 ivar?

【问题讨论】:

    标签: objective-c compiler-construction header-files ivar llvm-clang


    【解决方案1】:

    声明实例变量的唯一地方是在接口或类扩展(实际上是接口的扩展)中。但是您可以随时使用 associated object functions 在现代运行时有效地添加实例变量。

    【讨论】:

      【解决方案2】:

      如果您正在实现一个库并希望隐藏您的实例变量,请查看 Apple 在 UIWebView 界面中所做的工作。他们有一个不公开头文件的内部 webview。

      @class UIWebViewInternal;
      @protocol UIWebViewDelegate;
      
      UIKIT_CLASS_AVAILABLE(2_0) @interface UIWebView : UIView <NSCoding, UIScrollViewDelegate> { 
       @private
          UIWebViewInternal *_internal;
      }
      

      【讨论】:

        【解决方案3】:

        如果您只是在内部使用 ivar,并且您使用的是现代运行时(我认为是 Snow Leopard 64 位和 iOS 3.0+),那么您可以在类扩展中声明属性并合成它们课堂内。没有 ivars 暴露在你的标题中,没有凌乱的 id _internal 对象,你也可以绕过脆弱的 ivars。

        // public header
        @interface MyClass : NSObject {
        // no ivars
        }
        - (void)someMethod;
        @end
        
        // MyClass.m
        @interface MyClass ()
        @property (nonatomic, retain) NSString *privateString;
        @end
        
        @implementation MyClass
        @synthesize privateString;
        
        - (void)someMethod { 
            self.privateString = @"Hello";
            NSLog(@"self.privateString = %@", self.privateString);
            NSLog(@"privateString (direct variable access) = %@", privateString); // The compiler has synthesized not only the property methods, but also actually created this ivar for you. If you wanted to change the name of the ivar, do @synthesize privateString = m_privateString; or whatever your naming convention is
        }
        @end
        

        这适用于 Apple 的 gcc,以及 LLVM。 (我不确定这是否适用于其他平台,即不是 Apple 的 gcc,但它肯定适用于 iOS 和 Snow Leopard+)。

        【讨论】:

          猜你喜欢
          • 2010-10-26
          • 2011-03-01
          • 2018-06-15
          • 2019-08-31
          • 2015-11-19
          • 1970-01-01
          • 2010-09-22
          • 1970-01-01
          • 2016-09-29
          相关资源
          最近更新 更多