OC 类、协议、方法小结

2022/07/25 posted in  Apple
Tags:  #Objective-C

声明

.h 文件中使用@class 类名;声明,在 .m 文件中再引入具体头文件,有效避免重复引入。
初始化类时,如果不需要额外参数,则[[Class alloc] init]等同于[Class new]

// ByteDancer.h
@interface ByteDancer: NSObject
- (instancetype)initWithName:(NSString *)name;
@end

// ByteDancer.m
@implementation ByteDancer
- (instancetype)initWithName:(NSString *)name {
    // 注意!需要调用父类的init
    self = [super init];
    if (self) {
        self.name = name;
    }
    NSLog(@"A ByteDancer, %@ Joined!", name);
    return self;
}
@end

判断是否子类

// 字典对应的不确定类型
NSObject *getValue = [dictionary1 objectForKey:@"key1"];
if ([getValue isKindOfClass:NSString.class]) {
    // 确定是NSString 在转型成NSString
    NSString *strValue = (NSString *)getValue;
    [strValue length];
} else if([getValue isKindOfClass:ByteDancer.class]) {
    // 确定是ByteDancer 在转型成ByteDancer
    ByteDancer *byteDacner1 = (ByteDancer *)getValue;
    [byteDacner1 sayHello];
} else {
    NSLog(@"unkown class");
}

协议

协议的声明

// ByteDancerProtocol.h
@protocol SeniorLevel <NSObject>
- (void)doCodeReview;
@end
@protocol JuniorLevel <NSObject>
// id<SeniorLevel> 代表任何遵守SeniorLevel的类
- (void)assignMentor:(id<SeniorLevel>)mentor;
@end
@protocol Developer <NSObject>
- (bool)doCoding;
@end // 协议可以继承多个协议
@protocol ClientDeveloper <Developer>
@end

协议的遵循

#import "ByteDancerProtocol.h"
// ByteDancer.h
@interface SenioriOSDeveloper
: ByteDancer <SeniorLevel, ClientDeveloper>

@end
@interface JunioriOSDeveloper
: ByteDancer <JuniorLevel, ClientDeveloper>
// myMentor 类型是任何遵守 id<SeniorLevel> 的类
@property (strong, nonatomic) id<SeniorLevel> myMentor;
@end

方法

定义

16586576033933

判断能否响应方法

搭配 respondsToSelector 提前确认该对象是否响应消息
通常这种 interface没有声明还要使用performSelector去掉用的情况:

  • 第一个可能是这个方法是在运行时透过Runtime添加进来的方法,在编译时不存在
  • 第二种可能是在明确知道该对象有些实现私有方法,但没有声明在interface时,会使用 performSelector去掉用
MyClass *myObject = [[MyClass alloc] init];
if ([myObject respondsToSelector: @selector(numerOfDatasFrom:)]) {
    int dataCount = [myObject numerOfDatasFrom:@"main"];
    NSLog(@"%d", dataCount);
} else {
    // MyObject 不回应我的 numerOfDatasFrom 消息(没实现)
    int dataCount = -1;
    NSLog(@"%d", dataCount);
}
// NSObject.h
@protocol NSObject  
/** 发送指定的消息给对象, 返回消息执行结果(相当于方法调用) */  
- (id)performSelector:(SEL)aSelector;  
/** 发送带一个参数的消息给对象, 返回消息执行结果(相当于方法调用) */  
- (id)performSelector:(SEL)aSelector withObject:(id)object;  
/** 判断对象是否能够调用给定的方法 */  
- (BOOL)respondsToSelector:(SEL)aSelector; 
@end

// main.m
// 先判断对象是否能调用方法,再执行调用方法  
if ([bytedancer1 respondsToSelector:@selector(sayHello)]) {  
// 调用无参无返回值方法  
    [bytedancer1 performSelector:@selector(sayHello)];  
}  
// 可以用于调用私有方法
if ([bytedancer1 respondsToSelector:@selector(private_method)]) {  
    [bytedancer1 performSelector:@selector(private_method)];  
}

Objective-C 消息发送与转发机制原理