NSObject 类 | 青训营笔记

99 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的的第2天。

NSObject 类

1. 分配内存空间 & 初始化

在创建任何一个对象时,都会用到这两个方法 allocinit

首先调用的静态方法 alloc,系统会为这个对象分配内存并返回一个空的实例,之后再调用 init 实例方法进行初始化,通常子类也会覆盖这个方法去做相应的初始化,还有另外一个用法 new,它等于 alloc + init,我们自己定义的类或是其他系统类,也都可以使用 new 去创建对象,代替 alloc + init

// NSObject.h
@interface NSObject <NSObject> {  
/** 为新对象分配内存空间 */  
+ (instancetype)alloc;
/** 初始化对象 */  
- (instancetype)init;

/** 为新对象分配内存空间并初始化, 等于[[NSObject alloc] init] */  
+ (instancetype)new;
}
//main.m
MyClass *myClass1 = [[MyClass alloc] init];
// 等同于
MyClass *myClass2 = [MyClass new];

2. 发送消息(方法调用)

一种方法调用的方式是通过 performSelector 调用,它不会在编译时做任何的较验,也就是可以去创建一个该对象没有在 interface 声明的方法选择器并调用,由于没有编译器把关,如果该方法确实没有实现就会崩溃,所以一般在使用时会搭配 respondsToSelector 提前确认该对象是否响应消息。

// NSObject.h
@protocol NSObject  
/** 发送指定的消息给对象, 返回消息执行结果(相当于方法调用) */  
- (id)performSelector:(SEL)aSelector;  
/** 发送带一个参数的消息给对象, 返回消息执行结果(相当于方法调用) */  
- (id)performSelector:(SEL)aSelector withObject:(id)object;  
/** 判断对象是否能够调用给定的方法 */  
- (BOOL)respondsToSelector:(SEL)aSelector; 
@end
// main.m
// 先判断对象是否能调用方法,再执行调用方法  
if ([myClass1 respondsToSelector:@selector(sayHello)]) {  
// 调用无参无返回值方法  
    [myClass1 performSelector:@selector(sayHello)];  
}  
// 可以用于调用私有方法
if ([myClass1 respondsToSelector:@selector(private_method)]) {  
    [myClass1 performSelector:@selector(private_method)];  
}

3. 类关系判断

判断对象与对象之间类的关系,以及获取对象的类的方法。

类型 Class,不是对象,是一个类的型别。

// NSObject.h
/** 获取当前对象的类 */  
- (Class)class;
/** 获取当前对象的类 */  
- (Class)superclass;

/** 判断对象是否是给定类或给定类子类的实例 */  
- (BOOL)isKindOfClass:(Class)aClass;  
/** 判断对象是否是给定类的实例 */  
- (BOOL)isMemberOfClass:(Class)aClass;  
/** 判断对象是否遵从给定的协议 */  
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;  
// 字典对应的不确定类型
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");
}