有什么方法可以在Objective-C中添加不在头文件(不使用LLVM 2.0或更高版本)中的iVar?
问题描述:
我最近得知你可以在LLVM2.0的类扩展中添加ivar。 (海湾合作委员会不能这样做) 这是不知何故真正私人iVar,因为其他用户不存在,因为它不在头文件。 喜欢:有什么方法可以在Objective-C中添加不在头文件(不使用LLVM 2.0或更高版本)中的iVar?
//SomeClass.h
@interface SomeClass : NSObject {
}
@end
//SomeClass.m
@interface SomeClass()
{
NSString *reallyPrivateString;
}
@end
@implementation SomeClass
@end
但这依赖于编译器。是否有任何其他方式来声明不在头文件中的伊娃?
答
如果你正在实现一个库,并且想要隐藏你的实例变量,请看看苹果在UIWebView的界面中做了什么。他们有一个不公开头文件的内部webview。
@class UIWebViewInternal;
@protocol UIWebViewDelegate;
UIKIT_CLASS_AVAILABLE(2_0) @interface UIWebView : UIView <NSCoding, UIScrollViewDelegate> {
@private
UIWebViewInternal *_internal;
}
答
如果你只是要在内部使用的伊娃,你正在使用的现代运行时(雪豹64位和iOS 3.0+,我认为),那么你可以在一个类中声明属性扩展并在课堂内综合它们。没有ivars暴露在你的头部,没有杂乱的物体,并且你也可以在易碎的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
这适用于除了LLVM之外的Apple gcc。 (我不确定这是否适用于其他平台,即不是苹果的gcc,但它肯定适用于iOS和Snow Leopard +)。