协议(protocol)
关于协议的一些定义,简单使用方法就不多说了.
协议可以添加哪些:
1.添加方法(类方法/属性方法)
2.添加属性
关于协议添加属性来举个例子:
#import
@protocol PersonProtocol
@property (nonatomic, strong) NSString *name;//协议中的属性
@end
@interface Person : NSObject
@property (nonatomic, weak) id delegade;
@end
找个类实现协议
#import "Student.h"
@interface Student ()
@end
@implementation Student
//协议里的属性
@synthesize name;
@end
应用以下:
Person *onePerson = [Person new];
Student *xiaoming = [Student new];
onePerson.delegade = xiaoming;
onePerson.delegade.name = @"xiaoming";
NSLog(@"%@",xiaoming.name);
打印结果如下
xiaoming
通知(NSNotification)
先来看下常用的发通知的套路
发送:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"要发通知啦");
[[NSNotificationCenter defaultCenter] postNotificationName:@"aaa" object:nil];
NSLog(@"通知发完啦");
}
接收:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(testNoti) name:@"aaa" object:nil];
return YES;
}
- (void)testNoti {
NSLog(@"收到通知啦 %@",[NSThread currentThread]);
}
看下打印:
要发通知啦
收到通知啦 {number = 1, name = main}
通知发完啦
总结:
通过
postNotificationName:
发送通知是同步的, 会卡住当前线程. 就是说, 发送通知后,会等到对方接收到通知并执行完收到通知的方法后才会接着往下走.
关于移除通知
iOS 9以后UIViewController 添加通知后可以不用移除, 系统会自动给移除.
异步发送通知
异步发送通知需要三步
1.创建通知(NSNotification)
2.创建通知队列(NSNotificationQueue)
3.将通知放入队列中执行
发送:
NSLog(@"发送通知前");
//创建通知
NSNotification *noti = [[NSNotification alloc] initWithName:@"aaa" object:nil userInfo:nil];
//将通知加入队列,并设置为NSPostASAP,当当前runloop完成之后立即post
[[NSNotificationQueue defaultQueue] enqueueNotification:noti postingStyle:NSPostASAP];
NSLog(@"发送通知后");
接收:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(testNoti) name:@"aaa" object:nil];
return YES;
}
- (void)testNoti {
NSLog(@"接收到通知了%@",[NSThread currentThread]);
}
打印:
发送通知前
发送通知后
接收到通知了{number = 1, name = main}
将通知加入到队列的方法有个枚举参数:
typedef NS_ENUM(NSUInteger, NSPostingStyle) {
NSPostWhenIdle = 1, // 当runloop处于空闲状态时post
NSPostASAP = 2, // 当当前runloop完成之后立即post
NSPostNow = 3 // 立即post,同步(会立即执行)
};
指定枚举参数后, 队列会根据type, 在合适的时机将NSNotification 发送到NSNotificationCenter,这就达到了异步执行的效果.
NSPostWhenIdle
和NSPostASAP
差不多, 都会异步执行,NSPostNow
会立即执行
通知合并
将通知放入队列执行还有另外一个方法:
- (void)enqueueNotification:(NSNotification *)notification postingStyle:(NSPostingStyle)postingStyle coalesceMask:(NSNotificationCoalescing)coalesceMask forModes:(nullable NSArray
方法的第二个参数:(NSNotificationCoalescing)coalesceMask
就是控制通知的合并策略.
如下:
typedef NS_OPTIONS(NSUInteger, NSNotificationCoalescing) {
NSNotificationNoCoalescing = 0, // 不合成
NSNotificationCoalescingOnName = 1, // 根据NSNotification的name字段进行合成
NSNotificationCoalescingOnSender = 2 // 根据NSNotification的object字段进行合成
};
发送:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"发送通知前");
NSNotification *noti = [[NSNotification alloc] initWithName:@"aaa" object:nil userInfo:nil];
[[NSNotificationQueue defaultQueue] enqueueNotification:noti postingStyle:NSPostASAP];
[[NSNotificationQueue defaultQueue] enqueueNotification:noti postingStyle:NSPostWhenIdle];
[[NSNotificationQueue defaultQueue] enqueueNotification:noti postingStyle:NSPostWhenIdle coalesceMask:NSNotificationCoalescingOnName forModes:nil];
NSLog(@"发送通知后");
}
接收:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(testNoti) name:@"aaa" object:nil];
return YES;
}
- (void)testNoti {
NSLog(@"接收到通知了%@",[NSThread currentThread]);
}
打印:
发送通知前
发送通知后
接收到通知了{number = 1, name = main}
注意, 如果直接使用postNotificationName:或者指定NSPostNow提交方式或者指定合并策略为NSNotificationNoCoalescing 时,不会合并通知
参考:
http://www.cocoachina.com/ios/20170426/19124.html