发送消息(Sending Messages)
-
performSelector:withObject:afterDelay:
- 在当前线程延迟执行某个方法,定时器会以默认模式
NSDefaultRunLoopMode
运行。也就是说如果当前runloop不是默认模式的话,定时器不会执行。
- 在当前线程延迟执行某个方法,定时器会以默认模式
-
performSelector:withObject:afterDelay:inModes:
- 可以指定mode延迟执行某个方法。
-
performSelectorOnMainThread:withObject:waitUntilDone:
- 在主线程延迟执行某个方法
-
performSelectorOnMainThread:withObject:waitUntilDone:modes:
- 在主线程指定mode延迟执行某个方法
-
cancelPreviousPerformRequestsWithTarget:
- 取消执行某个方法
-
cancelPreviousPerformRequestsWithTarget:selector:object:
- 取消执行某个方法
-
performSelectorInBackground:withObject:
- 在新的子线程执行某个方法
消息转发(Forwarding Messages)
-
-
forwardingTargetForSelector:
- 消息转发,对象中找不到方法时会调用这个方法,如果可以执行就返回可用的方法,否则执行
methodSignatureForSelector:
方法对方法进行签名,如果返返回nil就抛出异常,否则就调用forwardInvocation:
进行尝试,如果还是不行就调用doesNotRecognizeSelector:
抛出异常。
- 消息转发,对象中找不到方法时会调用这个方法,如果可以执行就返回可用的方法,否则执行
-
forwardInvocation:
- 有子类重写来实现消息转发到其他对象。如果执行失败就调用
doesNotRecognizeSelector:
抛出异常。
- 有子类重写来实现消息转发到其他对象。如果执行失败就调用
动态执行(Dynamically Resolving Methods)
-
resolveClassMethod:
- 动态给类方法选择实现函数,返回YES标示找到了方法,否则就是找不到方法。然后就进入消息转发流程。
-
resolveInstanceMethod:
- 动态给对象方法选择实现函数,返回YES标示找到了方法,否则就是找不到方法。然后就进入消息转发流程。
- OC方法就是一个C函数,包含self和_cmd至少两个参数,使用
class_addMethod
方法可以将C函数添到的OC类上。
错误处理(Error Handling)
-
doesNotRecognizeSelector:
- 消息转发的最后一步,抛出异常。如果重写这个方法,必须调用super或者自己抛出异常。
归档(Archiving)
- 这个方式很少用,不是很了解,就不写那么多了。
对象方法(Instance Methods)
-
addObserver:forKeyPath:options:context:
- KVO监听属性
-
awakeFromNib
- xib加载完毕后会调用这个方法,可以这里做一些界面的处理
-
dictionaryWithValuesForKeys:
- 根据字典数组的key拿去对应的数据,必须保证key存在,否则返回nil
NSDictionary *temp1 = @{@"1":@"111",@"2":@"2222",@"3":@"333"};
NSDictionary *temp2 = [temp1 dictionaryWithValuesForKeys:@[@"1",@"4"]];
NSLog(@"temp2",temp2);
-
observeValueForKeyPath:ofObject:change:context:
- KVO监听属性的回调方法,这里会有新值旧值得回调
- (void)viewDidLoad {
[super viewDidLoad];
self.label = [UILabel new];
[self.label addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"text"];
self.label.text = @"111";
self.label.text = @"333";
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
NSLog(@"%@",change);
/*
// 第一次拿到的old是null,如果用的话要注意判断
{
kind = 1;
new = 111;
old = "<null>";
}
{
kind = 1;
new = 333;
old = 111;
}
*/
}
-
removeObserver:forKeyPath:
- 停止kvo监听,确保有注册kvo监听,否则调用这个方法回报错。
-
removeObserver:forKeyPath:context:
- 指定context去停止kvo监听,这个可以更加具体停止某一个kvo监听。确保有注册kvo监听,否则调用这个方法回报错。
-
setValue:forKey:
- 通过key设置属性的值
self.label = [UILabel new];
[self.label setValue:@"ddddd" forKey:@"text"];//self.label.text = @"dddd";
NSLog(@"text:%@",self.label.text);
-
setValue:forKeyPath:
- 指定路径设置属性的值,但是keypath是一个字符串容易出错,少用
[self setValue:@"eeee" forKeyPath:@"self.label.text"];
NSLog(@"text:%@",self.label.text);
-
setValue:forUndefinedKey:
- 在子类中重写这个方法,可以控制给一个不存在的key赋值不闪退,一般在model中会实现这个方法,这样就算服务端返回的字典和model不一致也不会报错。
- (void)viewDidLoad {
[super viewDidLoad];
// 这样随便写都不会闪退
[self setValue:@"dddd" forUndefinedKey:@"ddddd"];
}
// 这样重写一下就好
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
}
-
setValuesForKeysWithDictionary:
- 通过字典给多个属性同时赋值,要保证字典的key对应的属性都存在或者实现
setValue:forUndefinedKey:
方法,否则就会报错。
- 通过字典给多个属性同时赋值,要保证字典的key对应的属性都存在或者实现
NSDictionary *temp = @{@"text":@"ddddddddddddddd",@"title":@"song"};
[self setValuesForKeysWithDictionary:temp];
NSLog(@"title:%@",self.title);
-
valueForKey:
- 获取指定key的值
-
valueForKeyPath:
- 获取指定keypath的值
-
valueForUndefinedKey:
- 返回未定义的key的值,默认是抛出异常,可以在子类中重写这个类,返回一个默认值。
self.label.text = @"1234567890-=";
self.title = @"song"
NSLog(@"title:%@",[self valueForKey:@"title"]);
NSLog(@"text:%@",[self valueForKeyPath:@"self.label.text"]);
-
willChangeValueForKey:
- kvo过程中获取属性的值时会调用这个方法,但是如果要重写这个方法,必须使用super调用父类方法
类型方法(Type Methods)
-
debugDescription
- debug描述信息
-
hash
- 对象的hash值
NSObject相关方法到这里就完了,接下来看一下Object对象
Protocol NSObject
- NSObject 协议,NSObject直接遵守了NSObject协议,所以所以类和对象都遵守了这些协议。
-
class
当前类 -
superclass
父类 -
isEqual:
是否一致 -
hash
对象的hash值,唯一标识符 -
self
当前对象 -
isKindOfClass:
是否是属于某个类,会对父类也进行比较。 -
isMemberOfClass:
是否属于某个类,精确比较当前类,不对父类进行比较。 -
respondsToSelector:
是否相应某一个方法 -
conformsToProtocol:
是否遵守某协议 -
description
打印类或者对象的描述信息。 -
debugDescription
调试状态下打印的描述信息。 -
performSelector:
- 执行某个方法。执行时机有运行时时决定,如果执行的方法有返回值则无法保证可以获取最终结果。最好是使用
performSelectorOnMainThread:withObject:waitUntilDone:
或者dispatch_block来实现回调。
- 执行某个方法。执行时机有运行时时决定,如果执行的方法有返回值则无法保证可以获取最终结果。最好是使用
-
performSelector:withObject:
带有一个参数的执行某个方法 -
performSelector:withObject:withObject:
带有两个参数的执行某个方法 -
retain
引用计数加一 -
release
引用计数减一 -
autorelease
自动释放池 -
retainCount
引用计数数量
NSLog(@"self class %@",[self class]);
NSLog(@"self superclass %@",[self superclass]);
NSLog(@"self isEqual %zd",[self.label isEqual:lab]);
NSLog(@"self hash %zd - label %zd",self.hash,self.label.hash);
NSLog(@"self self %@",self);
// 这个会比较父类
NSLog(@"self isKindOfClass %zd",[self.label isKindOfClass:[UIView class]]);
NSLog(@"self isKindOfClass %zd",[self.label isKindOfClass:[UILabel class]]);
NSLog(@"self isKindOfClass %zd",[self.label isKindOfClass:[UIButton class]]);
// 这个精准比较当前类
NSLog(@"self isMemberOfClass %zd",[self.label isMemberOfClass:[UILabel class]]);
NSLog(@"self isMemberOfClass %zd",[self.label isMemberOfClass:[UIButton class]]);
NSLog(@"self isMemberOfClass %zd",[self.label isMemberOfClass:[UIViewController class]]);
NSLog(@"self conformsToProtocol %zd",[self conformsToProtocol:@protocol(NSObject)]);
NSLog(@"self description %@",self.description);
NSLog(@"self isProxy %zd",[self isProxy]);
NSLog(@"self.label isProxy %zd",[self.label isProxy]);
网友评论