Objective-C 的分类,协议和预处理

本文并不是一篇完整的教程,更像一篇快速笔记,讲解 Objective-C 中的分类,类扩展,协议和预处理。
分类
分类提供了一个简单的方式,用它可以将类的定义模块化到相关方法的分类中;它还提供了扩展现有类定义的简便方式,并且不必访问类的源代码,也无须创建子类。如下通过分类来扩展 DTShape 新增 sum 方法:
#import "DTShape.h"
@interface DTShape (MathOps)
- (int)sum:(int)length;
@end
在分类的实现中也可以访问类中属性和方法:
#import "DTShape+MathOps.h"
@implementation DTShape (MathOps)
- (int)sum:(int)length {
return self.numberOfSides * length;
}
@end
要使用分类,需要导入相应的头文件:
#import "DTShape+MathOps.h"
DTNamedShape *shape = [[DTNamedShape alloc] initWithName:@"square"];
shape.numberOfSides = 4;
[shape sum:4]
类的扩展
创建一个未命名的分类,且在括号 () 之间不指定名字,这是一种特殊的情况,这种特殊的语法定义为类的扩展;未命名分类是非常有用的,因为它们的方法都是私有的,如果需要写一个类,而且属性和方法仅供这个类本身使用,未命名分类比较合适:
@interface PWAbility ()
@property (copy, nonatomic) NSDictionary *commands;
@end
@implementation PWAbility
- (instancetype)init {
self = [super init];
if (self) {
_commands = @{PWTextCommand.msgType: PWTextCommand.class};
}
return self;
}
- (PWCommand *)commandWithData:(NSData *)data {
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSString *msgType = (NSString *)[json valueForKey:@"msgType"];
if (!msgType) {
return nil;
} else {
Class class = (Class)self.commands[msgType];
PWCommand<PWCommandReceivable> *command = [class new];
[command parseData:json];
return command;
}
}
@end
协议
协议列出了一组方法,有些可以是选择实现,有些是必须实现,如果决定实现特定协议的所有方法,也就意味着遵守这项协议:
- @required 后面的方法是必须实现,默认都是必须实现;
- @optional 后面的方法是选择实现。
@class PWListener;
@protocol PWListenerDelegate <NSObject>
- (void)listenerDidStartSuccess:(PWListener *)listener;
- (void)listenerDidStartFailed:(PWListener *)listener;
- (void)listener:(PWListener *)listener didConnectDevice:(PWLocalDevice *)device;
@end
@interface PWListener : NSObject
@property (weak, nonatomic) id<PWListenerDelegate> delegate;
- (instancetype)initWithAbility:(PWAbility *)ability port:(NSInteger)port;
- (void)start;
@end
预处理
预处理程序语句使用 # 标记,这个符号必须是一行中的第一个非空字符,顾名思义,预处理程序实际上是在分析 Objective-C 程序之前处理这些语句。
#define 就是给符号名称指定程序常量:
#define PI 3.141592654
#define TWO_PI 2 * 3.141592654
#import 导入头文件,”“ 在包含源文件的目录中查找,<> 只在特殊的系统头文件目录中寻找包含文件:
#import "PWAPIController.h"
#import <AFNetworking/AFNetworking.h>
#ifdef,#ifndef,#endif 是条件编译:
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#endif
#ifndef __OBJC__
#if USE_IL2CPP_PCH
#include "il2cpp_precompiled_header.h"
#endif
#endif
在 Xcode -> Target -> Build Settings 中设置: