“class-continuation分类”的5大用处
2019-07-25 本文已影响0人
蜗牛你慢慢来
- 通过“class-continuation分类”向类中新增实例变量。
假设我有一个绝密的类,不想给其他人知道,而我写的这个类拥有这个绝密的类的实例,而这个实例变量又声明在公共接口里面:
#import <Foundation/Foundation.h>
@classEOCSuperSecretClass;
NS_ASSUME_NONNULL_BEGIN
@interface EOCClass : NSObject
{
@private
EOCSuperSecretClass *_secretInstance;
}
@end
NS_ASSUME_NONNULL_END
那么,信息就泄露了,别人就会知道有个叫做EOCSuperSecretClass的类。为解决此问题,你也许会说,可以不把实例变量声明为强类型,而是将其类型由EOCSuperSecretClass * 改为id。然而,这么做不够好,因为在类的内部使用此实例时,无法得到编译器的帮助。没必要只因为想对外界隐藏某个内容就放弃编译器的辅助检查功能。这个问题可以由“class-continuation分类”来解决。那个代表绝密类的实例可以声明成这样:
//EOCClass.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface EOCClass : NSObject
@end
NS_ASSUME_NONNULL_END
//EOCClass.m
#import "EOCClass.h"
#import "EOCSuperSecretClass.h"
@interfaceEOCClass()
{
EOCSuperSecretClass *_secretInstance;
}
@end
@implementation EOCClass
//Methods here
@end
-
编写Objective-C++
Objective-C++是Objective-C与C++的混合体,其代码可以用这两种语言来编写。由于兼容性原因,游戏后端一般用C++来写。另外,有时候要使用的第三方库可能只有C++绑定,此时也必须使用C++来编码。 -
将public接口中声明为“只读”的属性扩展为“可读写”,以便在类的内部设置其值。这样,封装在类中的数据就由实例本身来控制,而外部代码则无法修改其值。
// EOCPerson.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface EOCPerson : NSObject
@property (nonatomic, copy, readonly) NSString *firstName;
@property (nonatomic, copy, readonly) NSString *lastName;
-(id)initWithFirstName:(NSString *)firstName
lastName:(NSString *)lastName;
@end
NS_ASSUME_NONNULL_END
// EOCPerson.m
@interfaceEOCPerson()
@property (nonatomic, copy, readwrite) NSString *firstName;
@property (nonatomic, copy, readwrite) NSString *lastName;
@end
@implementation EOCPerson
-(void)someMethod
{
NSString *test = @"test";
//在class-continuation分类中不管有没有定义readwrite,这个_firstName都可以赋值
_firstName = test;
//只有分类中定义了readwrite,才可以使用点语法和setFirstName:设置方法
self.firstName = test;
[self setFirstName:test];
}
@end
- 只会在类的实现代码中用到的私有方法也可以声明在“class-continuation分类”中。这么做比较合适,因为它描述了那些只在类实现代码中才会使用的方法。这些方法可以这样写:
@interfaceEOCPerson()
//私有方法
-(void)p_privateMethod;
@end
@implementation EOCPerson
-(void)p_privateMethod
{
}
@end
- 若对象所遵从的协议只应视为私有,则可在“class-continuation分类”中声明。有时由于对象所遵从的某个协议在私有API中,所以我们可能不太想在公共接口中泄露这一信息。
#import "EOCPerson.h"
#import "EOCSecretDelegate.h"
@interfaceEOCPerson() <EOCSecretDelegate>
@end
@implementation EOCPerson
/*… */
@end