iam*_*4de 5 private header declaration objective-c instance-variables
我遇到了一个用Objective C编写的库(我只有头文件和.a二进制文件).在头文件中,它是这样的:
@interface MyClass : MySuperClass
{
//nothing here
}
@property (nonatomic, retain) MyObject anObject;
- (void)someMethod;
Run Code Online (Sandbox Code Playgroud)
我怎样才能实现同样的目标?如果我尝试在接口的{}内声明没有相应ivar的属性,编译器会给我一个错误.最后,我想在.a中隐藏我的类的内部结构,并将必要的方法暴露给头文件.如何在.m中声明实例变量?类别不允许我添加ivar,只是方法.
bbu*_*bum 14
对于64位应用程序和iPhone应用程序(虽然不在模拟器中),属性合成也能够合成实例变量的存储.
即这是有效的:
@interface MyClass : MySuperClass
{
//nothing here
}
@property (nonatomic, retain) MyObject *anObject;
@end
@implementation MyClass
@synthesize anObject;
@end
Run Code Online (Sandbox Code Playgroud)
如果您编译32位Mac OS X或iPhone模拟器,编译器将给出错误.
小智 13
您可以使用Cocoa类中使用的相同习语.如果您查看NSString.h中的NSString类接口,您将看到没有声明实例变量.深入了解GNUstep源代码,您将找到诀窍.
请考虑以下代码.
@interface MyClass : NSObject
// Your methods here
- (void) doSomething;
@end
Run Code Online (Sandbox Code Playgroud)
@interface MyClassImpl : MyClass {
// Your private and hidden instance variables here
}
@end
@implementation MyClass
+ (id) allocWithZone:(NSZone *)zone
{
return NSAllocateObject([MyClassImpl class], 0, zone);
}
// Your methods here
- (void) doSomething {
// This method is considered as pure virtual and cannot be invoked
[self doesNotRecognizeSelector: _cmd];
}
@end
@implementation MyClassImpl
// Your methods here
- (void) doSomething {
// A real implementation of doSomething
}
@end
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,诀窍在于重载allocWithZone:在您的类中.此代码由NSObject提供的默认alloc调用,因此您不必担心应该使用哪种分配方法(两者都有效).在这样的allocWithZone:中,您可以使用Foundation函数NSAllocateObject()来为MyClassImpl对象而不是MyClass分配内存并初始化isa.之后,用户透明地处理MyClassImpl对象.
当然,您的类的真正实现应由MyClassImpl提供.MyClass的方法应以将消息作为错误接收的方式实现.
您可以使用类扩展.类扩展类似于类别但没有任何名称.在Apple文档中,他们只定义私有方法,但实际上您也可以声明内部变量.
@class PublicClass;
// Public interface
@interface MyClass : NSObject
@property (nonatomic, retain) PublicClass *publicVar;
@property (nonatomic, retain) PublicClass *publicVarDiffInternal;
- (void)publicMethod;
@end
Run Code Online (Sandbox Code Playgroud)
#import "PublicClass.h"
#import "InternalClass.h"
// Private interface
@interface MyClass ( /* class extension */ )
{
@private
// Internal variable only used internally
NSInteger defaultSize;
// Internal variable only used internally as private property
InternalClass *internalVar;
@private
// Internal variable exposed as public property
PublicClass *publicVar;
// Internal variable exposed as public property with an other name
PublicClass *myFooVar;
}
@property (nonatomic, retain) InternalClass *internalVar;
- (void)privateMethod;
@end
// Full implementation of MyClass
@implementation MyClass
@synthesize internalVar;
@synthesize publicVar;
@synthesize publicVarDiffInternal = myFooVar
- (void)privateMethod
{
}
- (void)publicMethod
{
}
- (id)init
{
if ((self = [super init]))
{
defaultSize = 512;
self.internalVar = nil;
self.publicVar = nil;
self.publicVarDiffInternal = nil; // initialize myFooVar
}
return self;
}
@end
Run Code Online (Sandbox Code Playgroud)
您可以将MyClass.h提供给只有您的公共API和公共属性的任何人.在MyClass.m上,您在类扩展上声明您的成员变量private和public,以及您的私有方法.
像这样,很容易公开公共接口并隐藏详细实现.我在没有任何麻烦的情况下使用了我的项目.
不,你不能。但如果您不使用,您可以这样做@property:
@interface X : Y {
struct X_Impl* impl;
}
-(int)getValue;
@end
Run Code Online (Sandbox Code Playgroud)
struct X_Impl {
int value;
};
...
@implementation X
-(void)getValue {
return impl->value * impl->value;
}
@end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7845 次 |
| 最近记录: |