編號 | 主題 | 內容 |
---|---|---|
一 | NSFileManager | NSFileManager介紹/用法(常見的判斷)/文件訪問/文件操做 |
二 | 集合對象的內存管理 | 集合對象的內存管理/內存管理總結 |
三 | *copy | copy基本概念/使用/copy快速入門/內存管理 |
四 | @Property中的copy關鍵字 | @property中的copy的做用/@property內存管理策略選擇 |
五 | 自定義類實現copy操做 | 自定義類實現copy操做 |
六 | 單例設計模式 | 單例模式概念/簡單的單例模式實現 |
七 | 宏定義抽取單例 |
什麼是NSFileManager程序員
NSFileManager使用了單例模式設計模式
單例
對象[NSFileManager defaultManager]
NSFileManager *manager = [NSFileManager defaultManager]; // 能夠判斷文件 BOOL flag = [manager fileExistsAtPath:@"/Users/MJ-Hee/Desktop/lnj.txt"]; NSLog(@"flag = %i", flag); // 能夠判斷文件夾 flag = [manager fileExistsAtPath:@"/Users/MJ-Hee/Desktop/未命名文件夾"]; NSLog(@"flag = %i", flag);
NSFileManager *manager = [NSFileManager defaultManager]; BOOL directory = NO; BOOL flag = [manager fileExistsAtPath:@"/Users/MJ-Hee/Desktop/未命名文件夾" isDirectory:&directory]; NSLog(@"flag = %i, directory = %i", flag, directory);
- (BOOL)isReadableFileAtPath:(NSString *)path;數組
- (BOOL)isWritableFileAtPath:(NSString *)path;多線程
系統目錄不容許寫入app
- (BOOL)isDeletableFileAtPath:(NSString *)path;atom
系統目錄不容許刪除spa
NSFileManager *manager = [NSFileManager defaultManager]; NSDictionary *dict = [manager attributesOfItemAtPath:@"/Users/MJ-Hee/Desktop/hmj.txt" error:nil]; NSLog(@"dit = %@", dict);
- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error;線程
- (NSData )contentsAtPath:(NSString )path;設計
NSFileManager *manager = [NSFileManager defaultManager]; NSArray *paths = [manager contentsOfDirectoryAtPath:@"/Users/MJ-Hee/Desktop" error:nil]; NSLog(@"paths = %@", paths);
- (NSArray )subpathsAtPath:(NSString )path;指針
- (NSArray *)subpathsOfDirectoryAtPath:(NSString *)path error:(NSError **)error;
NSFileManager *manager = [NSFileManager defaultManager]; NSArray *paths = [manager subpathsAtPath:@"/Users/LNJ/Desktop/"]; NSLog(@"paths = %@", paths);
- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;
- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;
- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error;
- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error;
NSFileManager *manager = [NSFileManager defaultManager]; BOOL flag = [manager createDirectoryAtPath:@"/Users/LNJ/Desktop/test" withIntermediateDirectories:YES attributes:nil error:nil]; NSLog(@"flag = %i", flag);
NSString *str = @"lnj"; //NSData : 二進制數據 //將字符串轉化成二進制數據 NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding]; NSFileManager *manager = [NSFileManager defaultManager]; BOOL flag = [manager createFileAtPath:@"/Users/LNJ/Desktop/abc.txt" contents:data attributes:nil]; NSLog(@"flag = %i", flag);
NSMutableArray *arr = [[NSMutableArray alloc] init]; Person *p = [[Person alloc] init]; NSLog(@"retainCount = %lu", [p retainCount]); //若是將一個對象添加到一個數組/字典中,那麼數組會對對象進行一次retain [arr addObject:p]; NSLog(@"retainCount = %lu", [p retainCount]); [p release]; NSLog(@"retainCount = %lu", [p retainCount]); //當數組對象釋放後,會給數組中全部的對象發送一條release消息 [arr release];
NSMutableArray *arr = [[NSMutableArray alloc] init]; Person *p = [[Person alloc] init]; NSLog(@"retainCount = %lu", [p retainCount]); [arr addObject:p]; NSLog(@"retainCount = %lu", [p retainCount]); //當數組移除一個對象以後,會給這個對象發送一條release消息 [arr removeObject:p]; NSLog(@"retainCount = %lu", [p retainCount]); [p release]; [arr release];
1.官方內存管理原則
2.集合的內存管理細節
3.廣泛規律
什麼是copy
常見的複製有:文件複製
特色:
OC中的copy
如何使用copy功能
使用copy功能的前提
@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
NSString *srcStr = @"lnj"; NSString *copyStr = [srcStr copy]; NSLog(@"src = %p, copy = %p", srcStr, copyStr);
NSString *srcStr = @"lnj"; NSMutableString *copyStr = [srcStr mutableCopy]; NSLog(@"src = %p, copy = %p", srcStr, copyStr); NSLog(@"src = %@, copy = %@", srcStr, copyStr); [copyStr appendString:@" cool"]; NSLog(@"src = %@, copy = %@", srcStr, copyStr); NSMutableString *srcStr = [NSMutableString stringWithFormat:@"lnj"]; NSString *copyStr = [srcStr copy]; [srcStr appendString:@" cool"]; NSLog(@"src = %p, copy = %p", srcStr, copyStr); NSLog(@"src = %@, copy = %@", srcStr, copyStr); NSMutableString *srcStr = [NSMutableString stringWithFormat:@"lnj"]; NSMutableString *copyStr = [srcStr mutableCopy]; [srcStr appendString:@" cool"]; [copyStr appendString:@" 520it"]; NSLog(@"src = %p, copy = %p", srcStr, copyStr); NSLog(@"src = %@, copy = %@", srcStr, copyStr);
總結 +若是是淺拷貝,那麼系統會自動對源對象進行一次retain
淺拷貝的原則
@interface Person : NSObject //用retain,外界能夠修改內部的數據,此處改成copy能夠防止外界修改內部的數據 @property (nonatomic, retain) NSString *name; @end NSMutableString *str = [NSMutableString stringWithFormat:@"lnj"]; Person *p = [[Person alloc] init]; p.name = str; // person中的屬性會被修改 [str appendString:@" cool"]; NSLog(@"name = %@", p.name);
Person *p = [[Person alloc] init]; p.name = @"lnj"; Dog *d = [[Dog alloc] init]; d.age = 10; NSLog(@"retainCount = %lu", [d retainCount]); // 1 p.pBlock = ^{ // 報錯, 調用以前就銷燬了 NSLog(@"age = %d", d.age); }; [d release]; // 0 p.pBlock(); [p release];
Person *p = [[Person alloc] init]; p.name = @"lnj"; Dog *d = [[Dog alloc] init]; d.age = 10; NSLog(@"retainCount = %lu", [d retainCount]); // 1 p.pBlock = ^{ // 會對使用到的外界對象進行一次retain NSLog(@"age = %d", d.age); NSLog(@"retainCount = %lu", [d retainCount]); // 1 }; [d release]; // 1 p.pBlock(); [p release];
非ARC
ARC
zone: 表示空間,分配對象是須要內存空間的,若是指定了zone,就能夠指定 新建對象對應的內存空間。可是:zone是一個很是古老的技術,爲了不在堆中出現內存碎片而使用的。在今天的開發中,zone幾乎能夠忽略
在-(id)copyWithZone(NSZone *)zone方法中建立一個副本對象,而後將當前對象的值賦值給副本對象便可
無父類實現
-(id)copyWithZone(NSZone *)zone{ //class用於獲取一個類 CustomMode *custom = [[[self class] copyWithZone:zone] init]; Custom ->_a = [_a copyWithZone:zone]; Custom -> _c = _c;//不是對象的 直接賦值 Return custom; }
-(id)copyWithZone(NSZone *)zone{ CustomModel *custom = [super copyWithZone:zone]; //只調用子類特有的成員變量的setter方法便可 …. Return custom; }
什麼是單例模式:(Singleton)
什麼狀況下使用單例?
單例設計模式的要點:
類
方法static 類名 *_instance = nil; + (instancetype)allowWithZone:(struct _NSZone *)zone { //因爲全部的建立方法都會調用該方法,因此只須要在該方法中控制當前對象只建立一次便可 if (_instance == nil) { NSLog(@"建立了一個對象); _instance = [[super allowWithZone:zone] init; } return _instance; //如下代碼在多線程中也能保證只執行一次 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[super allowWithZone:zone] init]; } ;) return _instance; } //copyWithZone方法用什麼調用?對象 - (id)copyWithZone:(NSZone *)zone { return _instance; } - (id)mutableCopyWithZone:(NSZone *)zone { return _instance; } - (oneway void) release { //爲保證整個程序過程當中只有一份實例,在這個方法中什麼都不作 } - (instancetype)retain { return _instance; } - (NSUInteger)retainCount { //注意:爲了方便程序員之間溝通,通常狀況下不會在單例中返回retainCount = 1,而是返回一個比較大的值 return MAXFLOAT; }
// 如何判斷當前是ARC仍是MRC? // 能夠在編譯的時候判斷當前是不是ARC #if __has_feature(objc_arc) NSLog(@"ARC"); #else NSLog(@"MRC"); #endif
/*********Singleton.h**********/ // 之後就可使用interfaceSingleton來替代後面的方法聲明 #define interfaceSingleton(name) +(instancetype)share##name
#if __has_feature(objc_arc) // ARC #define implementationSingleton(name) \ + (instancetype)share##name \ { \ name *instance = [[self alloc] init]; \ return instance; \ } \ static name *_instance = nil; \ + (instancetype)allocWithZone:(struct _NSZone *)zone \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instance = [[super allocWithZone:zone] init]; \ }); \ return _instance; \ } \ - (id)copyWithZone:(NSZone *)zone{ \ return _instance; \ } \ - (id)mutableCopyWithZone:(NSZone *)zone \ { \ return _instance; \ } #else // MRC #define implementationSingleton(name) \ + (instancetype)share##name \ { \ name *instance = [[self alloc] init]; \ return instance; \ } \ static name *_instance = nil; \ + (instancetype)allocWithZone:(struct _NSZone *)zone \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instance = [[super allocWithZone:zone] init]; \ }); \ return _instance; \ } \ - (id)copyWithZone:(NSZone *)zone{ \ return _instance; \ } \ - (id)mutableCopyWithZone:(NSZone *)zone \ { \ return _instance; \ } \ - (oneway void)release \ { \ } \ - (instancetype)retain \ { \ return _instance; \ } \ - (NSUInteger)retainCount \ { \ return MAXFLOAT; \ } #endif /********自定義類.h中********/ #import "Singleton.h" interfaceSingleton(類名); /********自定義類.m中********/ implementationSingleton(類名)