一离例、單例模式
1.1 概述
單例模式可以保證App在程序運(yùn)行中,一個(gè)類只有唯一個(gè)實(shí)例悉稠,從而做到節(jié)約內(nèi)存宫蛆。
在整個(gè)App程序中,這一份資源是共享的的猛。
提供一個(gè)固定的實(shí)例創(chuàng)建方法耀盗。
1.2 系統(tǒng)為我們提供的單例類有哪些?
UIApplication(應(yīng)用程序?qū)嵗?
NSNotificationCenter(消息中心類)
NSFileManager(文件管理類)
NSUserDefaults(應(yīng)用程序設(shè)置)
NSURLCache(請(qǐng)求緩存類)
NSHTTPCookieStorage(應(yīng)用程序cookies池)
1.3 在哪些地方會(huì)用到單例模式
一般在程序中卦尊,經(jīng)常調(diào)用的類叛拷,如工具類、公共跳轉(zhuǎn)類等岂却,會(huì)采用單例模式
例如:登陸控制器忿薇,網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求,音樂(lè)播放器等一個(gè)工程需要使用多次的控制器或方法淌友。
1.4 單例的初始化
.h聲明方法
+ (SingleCase *)shareSingleCase;
.m實(shí)現(xiàn)
+ (SingleCase *)shareSingleCase {
static SingleCase *single = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
single = [[self alloc] init];
});
//dispatch_once 作用是整個(gè)程序的生命周期中煌恢,僅執(zhí)行一次某一個(gè)block對(duì)象骇陈。
return single;
}
二震庭、代理模式
2.1 概述
代理模式是一種消息傳遞方式,一個(gè)完整的代理模式包括:委托對(duì)象你雌、代理對(duì)象和協(xié)議器联。
2.2 名稱解釋
協(xié)議:用來(lái)指定代理雙方可以做什么二汛,必須做什么。
委托對(duì)象:根據(jù)協(xié)議指定代理對(duì)象需要完成的事拨拓,即調(diào)用協(xié)議中的方法肴颊。
代理對(duì)象:根據(jù)協(xié)議實(shí)現(xiàn)委托方需要完成的事,即實(shí)現(xiàn)協(xié)議中的方法渣磷。
2.3 應(yīng)用場(chǎng)景
當(dāng)一個(gè)類的某些功能需要由別的類來(lái)實(shí)現(xiàn)婿着,但是又不確定具體會(huì)是哪個(gè)類實(shí)現(xiàn)。
2.4 具體實(shí)現(xiàn)
//委托對(duì)象 NextViewController.h
#import <UIKit/UIKit.h>
@protocol SayDadDelegate <NSObject>
//1.聲明協(xié)議 @required表示必須實(shí)現(xiàn) @optional表示非必須 若沒(méi)有關(guān)鍵詞表示必須實(shí)現(xiàn)
@required
- (void)sayDad:(NSString *)str;
@optional
- (void)saySon:(NSString *)str;
@end
@interface NextViewController : UIViewController
//2.定義代理屬性 ARC下使用weak; MRC下使用assign 防止循環(huán)引用
@property (nonatomic, weak) id <SayDadDelegate> delegate;
@end
//委托對(duì)象 NextViewController.m
//6.委托方通知代理來(lái)執(zhí)行任務(wù)
//分別判斷是否設(shè)置代理 和 實(shí)現(xiàn)協(xié)議方法
if (self.delegate && [self.delegate respondsToSelector:@selector(sayDad:)]) {
[self.delegate sayDad:@"我就是你爸爸"];
if ([self.delegate respondsToSelector:@selector(saySon:)]) {
[self.delegate saySon:@"我就是你兒子"];
}
}
//代理對(duì)象 ViewController.m
#import "ViewController.h"
#import "NextViewController.h"
@interface ViewController ()<SayDadDelegate>//4.服從協(xié)議
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NextViewController *next = [[NextViewController alloc] init];
next.modalPresentationStyle = UIModalPresentationFullScreen;
//3.設(shè)置代理
next.delegate = self;
[self presentViewController:next animated:YES completion:nil];
}
//5.實(shí)現(xiàn)協(xié)議中的方法
- (void)sayDad:(NSString *)str {
NSLog(@"主界面--- %@", str);
}
- (void)saySon:(NSString *)str {
NSLog(@"主界面--- %@", str);
}
@end
三醋界、觀察者模式
3.1 概述
定義了一種一對(duì)多的依賴關(guān)系竟宋,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)發(fā)生變化時(shí)形纺,會(huì)通知所有觀察者對(duì)象丘侠,使它們能夠自動(dòng)更新自己。
3.2 應(yīng)用場(chǎng)景
iOS中的KVO逐样、NSNotication都是觀察者模式蜗字。
3.3 通知機(jī)制
通知機(jī)制與委托機(jī)制不同,前者是”一對(duì)多“的對(duì)象之間的通信脂新,后者是“一對(duì)一”的對(duì)象之間的通信挪捕。在通知機(jī)制中,對(duì)某個(gè)通知感興趣的所有對(duì)象都可以成為接收者争便。
//實(shí)現(xiàn)方式
//發(fā)送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"RefreshData" object:nil];
//注冊(cè)成為觀察者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadData)name:@"RefreshData" object:nil];
//具體實(shí)現(xiàn)
-(void)loadData{
}
//移除通知
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"RefreshData" object:nil];
}
3.4 KVO機(jī)制
KVO機(jī)制不像通知機(jī)制那樣通過(guò)一個(gè)通知中心觀察所有對(duì)象担神,而是在對(duì)象屬性變化時(shí)將通知直接發(fā)送給觀察者對(duì)象
//監(jiān)測(cè)應(yīng)用程序狀態(tài)變化,appStatus是我們要觀察的對(duì)象的屬性
在AppStatusObserver類中的代碼
@implementation AppStatusObersver
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
NSLog(@"%@ %@",keyPath,change[NSKeyValueChangeNewKey]);
}
在appDelagate類中的代碼
@interface AppDelegate ()
@property (nonatomic,strong)NSString *appStatus;
@property (nonatomic,strong)AppStatusObersver *observer;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.observer = [[AppStatusObersver alloc] init];
[self addObserver:self.observer forKeyPath:@"appStatus" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:nil];
self.appStatus = @"launch";
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
self.appStatus = @"inactive";
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
self.appStatus = @"background";
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
self.appStatus = @"foreground";
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
self.appStatus = @"active";
}
- (void)applicationWillTerminate:(UIApplication *)application {
self.appStatus = @"terminate";
}
@end