單例模式設計模式
是設計模式之一,使用頻率高,讓數據或對象在程序的各個地方都能訪問,保持惟一app
要素:atom
各個地方都能訪問方法spa
+ 靜態消息 只要導入類 就能訪問設計
保持惟一code
1.在靜態消息內限制對象的建立orm
2.外部不要調用allocserver
#import "MXSingleton.h"對象
staticMXSingleton * _instance;rem
@implementation MXSingleton
+(MXSingleton *)sharedInstance{
if (_instance == nil) {
_instance = [[MXSingletonalloc] init];
}
return_instance;
}
@end
單例模式下的共享數據
1.緣由
由於 單例模式的對象只有一個
因此 在程序中任何位置建立都應該返回這個對象
由於 在程序中任何地方均可以訪問
因此 這個返回的對象至關於在程序運行時共享
由於 這個返回的對象在程序中單例而且共享
因此 這個對象裏面的屬性能夠做爲共享數據
1) 可以讓你在不一樣的vc之間傳輸數據
目的:下降vc之間的耦合度
2) 還可以在任何對象之間傳送數據
3) 缺點
1. 你不夠控制哪些對象不能修改/查詢值
2. 你都不知道誰修改了 哪修改 怎麼改 是修改/查詢
修改的順序很難肯定
4) 注意:
1. 兩個VC之間聯繫緊密 還使用之前的正向/反向傳值
聯繫中致使中間對象平白無故增長傳輸屬性時
再改用單例模式傳值
6. 其它應用
1. 系統應用
[NSNotificationCenter defaultCenter];
[UIApplication sharedApplication];
[NSUserDefaults standardDefault];
+ sharedXxxxx
+ defaultXxxxx
+ standardXxxxx
2. 單例模式數據共享作爲模型層的數據中心
TRAppModel
@property (nonatomic, strong) NSMutableArray * contacts;
TRDataCenter
TRAppModel.h
#import <Foundation/Foundation.h>
#import "TRContact.h"
//DataCenter
@interface TRAppModel : NSObject
@property (nonatomic, strong) NSMutableArray * contacts;
//- (void) addContact:(TRContact *)contact;
- (void)save;
- (void)read;
+ (TRAppModel *) sharedInstance;
@end
TRAppModel.m
#import "TRAppModel.h"
#import "TRContact.h"
staticTRAppModel * _sharedInstance;
@implementation TRAppModel
- (id)init
{
self = [superinit];
if (self) {
self.contacts = [NSMutableArrayarray];
TRContact * contact = [[TRContactalloc] init];
contact.name = @"三喪";
contact.phoneNumber = @"911";
[self.contactsaddObject:contact];
}
returnself;
}
//- (void) addContact:(TRContact *)contact
//{
// [self.contacts addObject:contact];
// // 對文件進行追加寫入
//}
// 對象 -> 文件
- (void)save
{
NSLog(@"%@",NSHomeDirectory());
// 使用字符串| plist 歸檔均可以
// 我使用歸檔
NSMutableData *data = [NSMutableDatadata];
NSKeyedArchiver *archiver = [[NSKeyedArchiveralloc] initForWritingWithMutableData:data];
[archiver encodeObject:self.contactsforKey:@"contact"];
[archiver finishEncoding];
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dataPath = [documentsPath stringByAppendingPathComponent:@"data"];
[[NSFileManagerdefaultManager] createFileAtPath:dataPath contents:data attributes:nil];
}
// 文件 -> 對象
- (void)read
{
// 反歸檔
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dataPath = [documentsPath stringByAppendingPathComponent:@"data"];
NSData *data = [NSDatadataWithContentsOfFile:dataPath];
NSKeyedUnarchiver *unarchive = [[NSKeyedUnarchiveralloc] initForReadingWithData:data];
NSArray *array = [unarchive decodeObjectForKey:@"contact"];
self.contacts = [array mutableCopy];
}
+ (TRAppModel *) sharedInstance
{
if(_sharedInstance == nil){
_sharedInstance = [[TRAppModelalloc] init];
}
return_sharedInstance;
}
@end
2、單例模式抽出模型層
1. 效果
1) 能夠將數據統一放到模型層對象中
減小C層之間的交互
2) 能夠針對模型層增長存儲/讀取的消息
專門負責保存/恢復
3) 能夠將業務邏輯也抽到模型層中
3、 KVO
1. 什麼是KVO
Key Value Observer 鍵值觀察
2. 幹什麼的?
KVO
觀察一個對象的屬性的更改
3. 觀察者設計模式
1) 什麼是?
關注一個對象,當對象變更時,獲得通知
MXViewController.m
#import "MXViewController.h"
#import "MXPerson.h"
@interfaceMXViewController ()
@property(nonatomic,strong) MXPerson *person;
- (IBAction)textFieldName:(UITextField *)sender;
- (IBAction)levelChanged:(UIStepper *)sender;
@property (weak, nonatomic) IBOutletUILabel *labelName;
@property (weak, nonatomic) IBOutletUILabel *labelLevel;
@property (weak, nonatomic) IBOutletUIProgressView *progressViewLabel;
@end
@implementation MXViewController
- (void)viewDidLoad
{
[superviewDidLoad];
self.person = [[MXPersonalloc] init];
}
-(void)viewWillAppear:(BOOL)animated{
// KVO 觀察者模式 是對象觀察對象裏的屬性是否有變化
// 開始觀察若是有多個屬性就須要寫多個addObserver進行觀察
[self.personaddObserver:selfforKeyPath:@"name"options:NSKeyValueObservingOptionNewcontext:NULL]; // forKey表示要觀察的對象,new是表示一旦有新值變化了就會調用下面的方法
[self.personaddObserver:selfforKeyPath:@"level"options:NSKeyValueObservingOptionNewcontext:NULL];
}
// 一旦被觀察的對象有變化就會調用此方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"name"]) {
self.labelName.text = self.person.name;
}elseif ([keyPath isEqualToString:@"level"]){
self.labelLevel.text = self.person.level;
self.progressViewLabel.progress = [self.person.levelfloatValue]/6;
}
}
// 撤銷觀察
-(void)viewWillDisappear:(BOOL)animated{
[superviewDidAppear:animated];
[self.personremoveObserver:selfforKeyPath:@"name"];
[self.personremoveObserver:selfforKeyPath:@"level"];
}
- (IBAction)textFieldName:(UITextField *)sender {
self.person.name = sender.text;
}
- (IBAction)levelChanged:(UIStepper *)sender {
self.person.level = [NSStringstringWithFormat:@"%f",sender.value];
}
@end