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