前幾天面試富途證券,被問到添加通知的相關問題,當時有幾個問題答錯了,在此總結。
使用通知的要點
1.注冊多少次,他的執行代碼就會執行多少次
//1、注冊多個通知 for (int i =0; i<3; i++) {[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(notifycationMehod:) name:@"testNotifycation" object:nil];} //2、傳遞通知 [[NSNotificationCenter defaultCenter]postNotificationName:@"testNotifycation" object:nil];
輸出結果
2016-12-01 17:06:23.868 NotifycationDemo[28703:10079806] receive notifycation object (null) 2016-12-01 17:06:23.868 NotifycationDemo[28703:10079806] receive notifycation object (null) 2016-12-01 17:06:23.869 NotifycationDemo[28703:10079806] receive notifycation object (null)
2.雖然注冊多次通知,但是移除一次通知,同一個對象通知就會全部移除
?
3.add和Remove相關方法成對出現我們平時在使用通知的時候可能會在viewWillAppear方法里面add觀察者,viewWillDisappear里面remove,但是我們如果忘記remove,那么如果我們導航到當前頁面再導航到另外一個頁面,然后再退回當前頁面,這時候我們會得到2個輸出結果。
- (void)viewWillAppear:(BOOL)animated{[super viewWillAppear:animated];//注冊通知[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(notifycationMehod:) name:@"testNotifycation" object:nil]; }- (void)viewWillDisappear:(BOOL)animated{[super viewWillDisappear:animated];//沒有remove通知 }
2016-12-01 17:24:13.722 NotifycationDemo[28820:10087367] receive notifycation object (null)
2016-12-01 17:24:13.723 NotifycationDemo[28820:10087367] receive notifycation object (null)
4.移除一個name沒有add的通知,不會崩潰
[[NSNotificationCenter defaultCenter]removeObserver:self name:@"unknownName" object:nil];
5 .?一個對象添加了觀察者,但是沒有移除,程序不會崩潰,這是為啥
@implementation NotifyTestClass- (void)registerMyNotifycation{[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(notifycationMehod) name:@"testNotifycation" object:nil]; }- (void)notifycationMehod{NSLog(@"NotifyTestClass receive notify"); }- (void)dealloc{NSLog(@"NotifyTestClass dealloc"); } @end//局部變量 立刻釋放NotifyTestClass *nt = [[NotifyTestClass alloc]init];[nt registerMyNotifycation]; //發送通知 [[NSNotificationCenter defaultCenter]postNotificationName:@"testNotifycation" object:nil];
輸出結果
2016-12-01 19:29:15.039 NotifycationDemo[29035:10119206] NotifyTestClass dealloc
蘋果官網文檔有說明,iOS 9.0之后NSNotificationCenter不會對一個dealloc的觀察者發送消息所以這樣就不會崩潰了。果真我換了一個8.1的手機測試,程序崩潰了,原來是做了優化。
6 .?ViewController對象在銷毀的時候,系統會對他監聽的通知進行清除
@implementation TwoViewController- (void)viewDidLoad {[super viewDidLoad];[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(notifycationMehod) name:@"testNotifycation" object:nil];// Do any additional setup after loading the view from its nib. } - (void)notifycationMehod{NSLog(@"TwoViewController receive notify"); } - (void)dealloc{NSLog(@"TwoViewController dealloc"); } @end
輸出結果
2016-12-02 16:36:42.175 NotifycationDemo[31359:10305477] TwoViewController dealloc 2016-12-02 16:36:42.176 NotifycationDemo[31359:10305477] removeObserver = <TwoViewController: 0x7fa42381d720>
7 .?處理方法是和post通知方法在同一線程同步執行的
因此我們如果要接受一些通知更新UI的時候,我們需要回到主線程來處理。
dispatch_async(dispatch_get_main_queue(), ^{//do your UI});
?
Reference:
NSNotificationCenter/NSNotification 使用注意點全面解析
深入思考NSNotification
?
?