1、单例模式
一、系統(tǒng)中的單例
1、UIApplication
1)一個iOS程序啟動后創(chuàng)建的第一個對象就是UIApplication對象,且只有一個(通過代碼獲取兩個UIApplication對象,打印地址可以看出地址是相同的)。
2)通過[UIApplication sharedApplication]可以獲得這個單例對象
3)利用UIApplication對象,能進行一些應(yīng)用級別的操作,如:
- 設(shè)置應(yīng)用程序圖標右上角的紅色提醒數(shù)字 @property(nonatomic) NSInteger applicationIconBadgeNumber;
- 設(shè)置聯(lián)網(wǎng)指示器的可見性 @property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
- 管理狀態(tài)欄在iOS7中,默認情況下,狀態(tài)欄都是由UIViewController管理的,所以,如果狀態(tài)欄的樣式只設(shè)置一次,那就用UIApplication來進行管理;如 果狀態(tài)欄是否隱藏,樣式不一樣那就用控制器進行管理。UIApplication來進行管理有額外的好處,可以提供動畫效果。
?狀態(tài)欄的樣式 ??- (UIStatusBarStyle)preferredStatusBarStyle;?
?狀態(tài)欄的可見性 -(BOOL)prefersStatusBarHidden;
4)openURL:方法
- 打電話? ??????? [app openURL:[NSURLURLWithString:@"tel://10086"]];
- 發(fā)短信 ?????????????? [app openURL:[NSURLURLWithString:@"sms://10086"]];
- 發(fā)郵件 ?????????????? [app openURL:[NSURLURLWithString:@"mailto://12345@qq.com"]];
- 打開一個網(wǎng)頁資源? [app openURL:[NSURLURLWithString:@"http://ios.itcast.cn"]];
- 打開其他app程序 ??openURL方法,可以打開其他APP。
5)代理
// 當(dāng)應(yīng)用程序啟動完畢的時候就會調(diào)用(系統(tǒng)自動調(diào)用) - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);// 即將失去活動狀態(tài)的時候調(diào)用(失去焦點, 不可交互) - (void)applicationWillResignActive:(UIApplication *)application;// 應(yīng)用程序進入后臺的時候調(diào)用 一般在該方法中保存應(yīng)用程序的數(shù)據(jù), 以及狀態(tài) - (void)applicationDidEnterBackground:(UIApplication *)application NS_AVAILABLE_IOS(4_0);// 應(yīng)用程序即將進入前臺的時候調(diào)用, 一般在該方法中恢復(fù)應(yīng)用程序的數(shù)據(jù),以及狀態(tài)- (void)applicationWillEnterForeground:(UIApplication *)application;// 應(yīng)用程序即將被銷毀的時候會調(diào)用該方法, 注意:如果應(yīng)用程序處于掛起狀態(tài)的時候無法調(diào)用該方法(void)applicationWillTerminate:(UIApplication *)application;// 應(yīng)用程序接收到內(nèi)存警告的時候就會調(diào)用, 一般在該方法中釋放掉不需要的內(nèi)存- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;?
2、NSNotificationCenter
1)? 通過[NSNotificationCenter defaultCenter]可以獲得這個單例對象
2)發(fā)通知
- [[NSNotificationCenter?defaultCenter]?postNotificationName:@"myNotice"?object:nil?userInfo:@{@"sendValue"?forKey:@"sendKey"}];
3)接受通知
- - (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;
? 4)只要往NSNotificationCenter注冊了,就必須有remove的存在
3、NSUserDefaults
1)? 通過[NSUserDefaults standardUserDefaults]可以獲得這個單例對象
2) ?支持的數(shù)據(jù)類型有:NSNumber(NSInteger、float、double),NSString,NSDate,NSArray,NSDictionary,BOOL.
3)? 注意事項
- 對相同的Key賦值約等于一次覆蓋,要保證每一個Key的唯一性
- NSUserDefaults 存儲的對象全是不可變的
- 不支持自定義對象的存儲,不過它支持NSData的類型
4)? 存儲自定義對象
- 將自定義類型轉(zhuǎn)換為NSData類型:必須實現(xiàn)NSCoding 協(xié)議,實現(xiàn)?encodeWithCoder 方法 和? initWithCoder 方法
- 自定義類型數(shù)據(jù)存入 NSUserDefaults 中
5)? 常用方法
- - (id)objectForKey:(NSString *)defaultName;通過標識符取出數(shù)據(jù)
- - (void)setObject:(id)value forKey:(NSString *)defaultName;通過標識符進行存儲
- - (void)removeObjectForKey:(NSString *)defaultName;通過名字來移除數(shù)據(jù)
- - (BOOL)synchronize;同步數(shù)據(jù)到磁盤中,這個方法是以一定周期間隔自動調(diào)用的,不想等待可以手動調(diào)用
?
4、NSFileManager
1)、沙盒機制:應(yīng)用只能訪問自己應(yīng)用目錄下的文件。(越獄機除外)
- Documents:蘋果建議將程序創(chuàng)建產(chǎn)生的文件以及應(yīng)用瀏覽產(chǎn)生的文件數(shù)據(jù)保存在該目錄下,iTunes備份和恢復(fù)的時候會包括此目錄
- Library:存儲程序的默認設(shè)置或其它狀態(tài)信息;
- Library/Caches:存放緩存文件,保存應(yīng)用的持久化數(shù)據(jù),用于應(yīng)用升級或者應(yīng)用關(guān)閉后的數(shù)據(jù)保存,不會被itunes同步,所以為了減少同步的時間,可以考慮將一些比較大的文件而又不需要備份的文件放到這個目錄下。
- tmp:提供一個即時創(chuàng)建臨時文件的地方,但不需要持久化,在應(yīng)用關(guān)閉后,該目錄下的數(shù)據(jù)將刪除,也可能系統(tǒng)在程序不運行的時候清除
?
- 獲取應(yīng)用沙盒根路徑:?
NSString *dirHome=NSHomeDirectory(); - 獲取Documents目錄路徑: //[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0];
- 獲取Library目錄路徑
- 獲取Cache目錄路徑:
?
2)通過[NSFileManager defaultManager]可以獲得這個單例對象
?
3)創(chuàng)建文件和創(chuàng)建文件夾
//創(chuàng)建文件 -(void *)createFile { NSString *documentsPath =[self dirDoc]; NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"]; NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"]; BOOL res=[fileManager createFileAtPath:testPath contents:nil attributes:nil]; if (res) { NSLog(@"文件創(chuàng)建成功: %@" ,testPath); }else NSLog(@"文件創(chuàng)建失敗"); } //創(chuàng)建文件夾 -(void *)createDir { NSString *documentsPath =[self dirDoc]; NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"]; // 創(chuàng)建目錄 BOOL res=[fileManager createDirectoryAtPath:testDirectory withIntermediateDirectories:YES attributes:nil error:nil]; if (res) { NSLog(@"文件夾創(chuàng)建成功"); }else NSLog(@"文件夾創(chuàng)建失敗"); }}
?
4)刪除文件和文件夾
//刪除文件 -(void)deleteFile { NSString *documentsPath =[self dirDoc]; NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"]; NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"]; BOOL res=[fileManager removeItemAtPath:testPath error:nil]; if (res) { NSLog(@"文件刪除成功"); }else NSLog(@"文件刪除失敗"); NSLog(@"文件是否存在: %@",[fileManager isExecutableFileAtPath:testPath]?@"YES":@"NO"); }}
-(void)deleteDir
{
NSString *documentsPath =[self dirDoc]; NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"]; NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL res=[fileManager removeItemAtPath:testDirectory error:nil]; if (res) { NSLog(@"文件夾刪除成功"); }else NSLog(@"文件夾刪除失敗"); NSLog(@"文件夾是否存在: %@",[fileManager isExecutableFileAtPath:testPath]?@"YES":@"NO");
}
}
5)移動文件到另一個文件夾和復(fù)制文件夾
//從一個文件夾中移動A文件到另一個文件夾-(BOOL)moveDiectory:(NSString*)nowparh prePath:(NSString*)prePath {if (nowparh == nil || nowparh.length == 0) return NO;if (prePath == nil || prePath.length == 0) return NO;NSFileManager * fileManager = [NSFileManager defaultManager];if ([fileManager fileExistsAtPath:prePath]){NSError * error;[fileManager moveItemAtPath:prePath toPath:nowparh error:&error];if (error){PSLog(@"error:%@",error);return NO;};return YES;}return NO; }
//從A文件夾中復(fù)制文件到B文件夾中 -(BOOL)copyDirectory:(NSString*)nowpath prepath:(NSString*)prepath {if (nowpath == nil || nowpath.length == 0) return NO;if (prepath == nil || prepath.length == 0) return NO;NSFileManager * fileManager = [NSFileManager defaultManager];if ([fileManager fileExistsAtPath:prepath]){NSError * error;[fileManager copyItemAtPath:prepath toPath:nowpath error:&error];if (error){PSLog(@"error:%@",error);return NO;}return YES;}return NO; }
?
二、單例模式定義
? 保證一個類僅有一個實例對象,并提供了一個訪問它的全局訪問點。
?
三、適合場合
1、類只能有一個實例。
2、只能共享資源而不能復(fù)制的資源類。
?
四、優(yōu)缺點
1、共享信息,易于外界訪問。
2、作為一個管理中心。
3、破壞了封裝性,耦合度高。
?
五、創(chuàng)建嚴格的單例
1、防止子類繼承
2、確保實例對象只創(chuàng)建一個
3、防止單例對象被提前釋放掉
@implementation AcountManagerCenterstatic AcountManagerCenter *center = nil;+ (instancetype)sharedManagerCenter {static dispatch_once_t once;dispatch_once(&once, ^{center = (AcountManagerCenter *)@"AcountManagerCenter";center = [[AcountManagerCenter alloc]init];});//防止子類使用NSString *classString = NSStringFromClass([self class]);if ([classString isEqualToString:@"AcountManagerCenter"] == NO) {NSParameterAssert(nil);}return center; }- (instancetype)init {NSString *string = (NSString *)center;//確保實例對象只創(chuàng)建一個if ([string isKindOfClass:[NSString class]]&&[string isEqualToString:@"AcountManagerCenter"]) {self = [super init];if (self) {}return self;}else{return nil;}}
?
六、實際應(yīng)用-為登錄用戶實現(xiàn)賬號本地存儲
?1、創(chuàng)建一個賬號管理中心的一個單例
.h?文件 #import <Foundation/Foundation.h>@interface AcountManagerCenter : NSObject+(AcountManagerCenter *)sharedManagerCenter;//存儲數(shù)據(jù) -(void)setAcountValue:(id)value withKey:(NSString *)key;//讀取數(shù)據(jù) -(id)valueWithKey:(NSString *)key;@end.m?文件 #import "AcountManagerCenter.h" #import "FastCoder.h"@implementation AcountManagerCenterstatic AcountManagerCenter *center = nil;+ (instancetype)sharedManagerCenter {static dispatch_once_t once;dispatch_once(&once, ^{center = (AcountManagerCenter *)@"AcountManagerCenter";center = [[AcountManagerCenter alloc]init];});//防止子類使用NSString *classString = NSStringFromClass([self class]);if ([classString isEqualToString:@"AcountManagerCenter"] == NO) {NSParameterAssert(nil);}return center; }- (instancetype)init {NSString *string = (NSString *)center;//確保實例對象只創(chuàng)建一個if ([string isKindOfClass:[NSString class]]&&[string isEqualToString:@"AcountManagerCenter"]) {self = [super init];if (self) {}return self;}else{return nil;}}-(void)setAcountValue:(id)value withKey:(NSString *)key {NSParameterAssert(value);NSParameterAssert(key);NSData *data = [FastCoder dataWithRootObject:value];if (data) {[[NSUserDefaults standardUserDefaults] setObject:data forKey:key];}}-(id)valueWithKey:(NSString *)key {NSParameterAssert(key);NSData *data = [[NSUserDefaults standardUserDefaults] valueForKey:key];return [FastCoder objectWithData:data];}2、封裝上層接口(為NSObject拓展一個分類)
分類.h文件 #import <Foundation/Foundation.h>@interface NSObject (AcountManagerCenter)-(void)saveValueForKey:(NSString *)key;+(id)valueByKey:(NSString *)key;@end分類.m文件 #import "NSObject+AcountManagerCenter.h" #import "AcountManagerCenter.h"@implementation NSObject (AcountManagerCenter)-(void)saveValueForKey:(NSString *)key {[[AcountManagerCenter sharedManagerCenter] setAcountValue:self withKey:key]; }+(id)valueByKey:(NSString *)key {return [[AcountManagerCenter sharedManagerCenter] valueWithKey:key]; }@end3、為客戶端實現(xiàn)存儲賬號
#import "ViewController.h" #import "CTAcount.h" #import "NSObject+AcountManagerCenter.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];CTAcount *acount = [[CTAcount alloc]init];acount.name = @"chen";acount.age = @(20);acount.acount = @"admin";acount.password = @"123456";[acount saveValueForKey:@"chen"];CTAcount *acount1 = [CTAcount valueByKey:@"chen"];NSLog(@"%@,%@",acount1.age,acount1.acount);}@end?
七、推薦第三方-FastCoding
這是一個快速、靈活存儲二進制文件格式的第三方,它可以不用手動的實現(xiàn)NSCoding協(xié)議就可以將自定義類型對象轉(zhuǎn)化為NSData類型數(shù)據(jù),它可以代替NSCoding,屬性列表和JSON。
登錄GitHub,在搜索欄中搜索FastCoding,然后下載下來將FastCoder.h 和 FastCoder.m添加到自己的工程中。
?
轉(zhuǎn)載于:https://www.cnblogs.com/panghuangios/p/5313636.html
總結(jié)
- 上一篇: 女人早上梦到蛇预示着什么
- 下一篇: 5、android使用意图传递数据之全局