【问题标题】: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
【解决方案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+)。