一、NSDictionary基本概念
1.1什么是NSDictionary
- NSDictionary翻譯過來叫做”字典”
- 日常生活中,“字典”的作用:通過一個拼音或者漢字,就能找到對應的詳細解釋
- NSDictionary的作用類似:通過一個key,就能找到對應的value
- NSDictionary是不可變的, 一旦初始化完畢, 里面的內容就無法修改
1.2NSDictionary的創建
- (instancetype)dictionary;
- (instancetype)dictionaryWithObject:(id)object forKey:(id lt;NSCopyinggt;)key;
- (instancetype)dictionaryWithObjectsAndKeys:(id)firstObject, ...;
- (id)dictionaryWithContentsOfFile:(NSString *)path;
- (id)dictionaryWithContentsOfURL:(NSURL *)url;
- NSDictionary創建簡寫
- 以前
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@quot;lnjquot;, @quot;namequot;, @quot;12345678quot;, @quot;phonequot;, @quot;天朝quot;, @quot;addressquot;, nil];
- 現在
NSDictionary *dict = @{@quot;namequot;:@quot;lnjquot;, @quot;phonequot;:@quot;12345678quot;, @quot;addressquot;:@quot;天朝quot;};
- 以前
- NSDictionary獲取元素簡寫
- 以前
[dict objectForKey:@quot;name”];
- 現在
dict[@quot;name”];
- 以前
- 鍵值對集合的特點
- 字典存儲的時候,必須是quot;鍵值對quot;的方式來存儲(同時鍵不要重復)
- 鍵值對中存儲的數據是quot;無序的quot;.
- 鍵值對集合可以根據鍵, 快速獲取數據.
1.3NSDictionary的遍歷
- -(NSUInteger)count;
- 返回字典的鍵值對數目
-
-(id)objectForKey:(id)aKey;
- 根據key取出value
-
快速遍歷
NSDictionary *dict = @{@quot;namequot;:@quot;lnjquot;, @quot;phonequot;:@quot;12345678quot;, @quot;addressquot;:@quot;天朝quot;}; for (NSString *key in dict) { NSLog(@quot;key = %@, value = http://www.tuicool.com/articles/%@quot;, key, dict[key]); }
- Block遍歷
[dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) { NSLog(@quot;key = %@, value = http://www.tuicool.com/articles/%@quot;, key, obj); }];
1.4NSDictionary文件操作
- 將字典寫入文件中
- -(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
- -(BOOL)writeToURL:(NSURL *)url atomically:(BOOL)atomically;
- 存結果是xml文件格式,但蘋果官方推薦為plist后綴。
示例:
NSDictionary *dict = @{@quot;namequot;:@quot;lnjquot;, @quot;phonequot;:@quot;12345678quot;, @quot;addressquot;:@quot;天朝quot;}; BOOL flag = [dict writeToFile:@quot;/Users/LNJ/Desktop/dict.plistquot; atomically:YES]; NSLog(@quot;flag = %iquot;, flag);
- 從文件中讀取字典
NSDictionary *newDict = [NSDictionary dictionaryWithContentsOfFile:@quot;/Users/LNJ/Desktop/dict.plistquot;]; NSLog(@quot;newDict = %@quot;, newDict);
二、NSMutableDictionary基本概念
2.1NSMutableDictionary 基本概念
- 什么是NSMutableDictionary
- NSMutableDictionary是NSDictionary的子類
- NSDictionary是不可變的,一旦初始化完畢后,它里面的內容就永遠是固定的,不能刪除里面的元素, 也不能再往里面添加元素
- NSMutableDictionary是可變的,隨時可以往里面添加\更改\刪除元素
2.2NSMutableDictionary的常見操作
- -(void)setObject:(id)anObject forKey:(id )aKey;
- 添加一個鍵值對(會把aKey之前對應的值給替換掉)
- -(void)removeObjectForKey:(id)aKey;
- 通過aKey刪除對應的value
- -(void)removeAllObjects;
- 刪除所有的鍵值對
2.3NSMutableDictionary的簡寫
- 設置鍵值對
- 以前
[dict setObject:@quot;Jackquot; forKey:@quot;name”];
- 現在
dict[@quot;namequot;] = @quot;Jackquot;;
- 以前
2.4NSDictionary和NSArray對比
- NSArray和NSDictionary的區別
- NSArray是有序的,NSDictionary是無序的
- NSArray是通過下標訪問元素,NSDictionary是通過key訪問元素
- NSArray的用法
- 創建
@[@quot;Jackquot;, @quot;Rosequot;] (返回是不可變數組)
- 訪問
id d = array[1];
- 賦值
array[1] = @quot;jackquot;;
- 創建
- NSDictionary的用法 創建
@{ @quot;namequot; : @quot;Jackquot;, @quot;phonequot; : @quot;10086quot; } (返回是不可變字典)
- 訪問
id d = dict[@quot;namequot;];
- 賦值
dict[@quot;namequot;] = @quot;jackquot;;
- 訪問
三、常見的結構體
3.1NSPoint和CGPoint
- CGPoint和NSPoint是同義的
typedef CGPoint NSPoint; CGPoint的定義struct CGPoint { CGFloat x; CGFloat y; }; typedef struct CGPoint CGPoint; typedef double CGFloat;
- CGPoint代表的是二維平面中的一個點
- 可以使用CGPointMake和NSMakePoint函數創建CGPoint
3.2NSSize和CGSize
- CGSize和NSSize是同義的
typedef CGSize NSSize; CGSize的定義struct CGSize { CGFloat width; CGFloat height; }; typedef struct CGSize CGSize;
- CGSize代表的是二維平面中的某個物體的尺寸(寬度和高度)
- 可以使用CGSizeMake和NSMakeSize函數創建CGSize
3.3NSRect和的CGRect
- CGRect和NSRect是同義的
typedef CGRect NSRect; CGRect的定義struct CGRect { CGPoint origin; CGSize size;}; typedef struct CGRect CGRect;
- CGRect代表的是二維平面中的某個物體的位置和尺寸
- 可以使用CGRectMake和NSMakeRect函數創建CGRect
3.4常見的結構體使用注意
- 蘋果官方推薦使用CG開頭的:
- CGPoint
- CGSize
- CGRect
四、NSNumber
4.1NSNumber基本概念
- NSArray\NSDictionary中只能存放OC對象,不能存放int\float\double等基本數據類
- 如果真想把基本數據(比如int)放進數組或字典中,需要先將基本數據類型包裝成OC對象
Paste_Image.png
- NSNumber可以將基本數據類型包裝成對象,這樣就可以間接將基本數據類型存進NSArray\NSDictionary中
Paste_Image.png
4.2NSNumber的創建
- 以前
(NSNumber *)numberWithInt:(int)value; (NSNumber *)numberWithDouble:(double)value; (NSNumber *)numberWithBool:(BOOL)value;
- 現在
@10; @10.5; @YES; @(num);
4.3從NSNumber對象中的到基本類型數據
- (char)charValue; - (int)intValue; - (long)longValue; - (double)doubleValue; - (BOOL)boolValue; - (NSString *)stringValue; - (NSComparisonResult)compare:(NSNumber *)otherNumber; - (BOOL)isEqualToNumber:(NSNumber *)number;
五、NSValue
5.1NSValue基本概念
- NSNumber是NSValue的子類, 但NSNumber只能包裝數字類型
- NSValue可以包裝任意值
- 因此, 可以用NSValue將結構體包裝后,加入NSArray\NSDictionary中
5.2常見結構體的包裝
- 為了方便 結構體 和NSValue的轉換,Foundation提供了以下方法
- 將結構體包裝成NSValue對象
(NSValue *)valueWithPoint:(NSPoint)point; (NSValue *)valueWithSize:(NSSize)size; (NSValue *)valueWithRect:(NSRect)rect;
- 從NSValue對象取出之前包裝的結構體
- (NSPoint)pointValue; - (NSSize)sizeValue; - (NSRect)rectValue;
5.3任意數據的包裝
- NSValue提供了下列方法來包裝任意數據
(NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type; value參數 : 所包裝數據的地址 type參數 : 用來描述這個數據類型的字符串, 用@encode指令來生成 - 從NSValue中取出所包裝的數據 - (void)getValue:(void *)value;
六、NSDate
6.1NSDate基本概念
- NSDate可以用來表示時間, 可以進行一些常見的日期\時間處理
- 一個NSDate對象就代表一個時間
- [NSDate date]返回的就是當前時間
NSDate *now = [NSDate date]; NSLog(@quot;now = %@quot;, now); // 設置轉換后的目標日期時區 NSTimeZone *zone = [NSTimeZone systemTimeZone]; // 得到源日期與世界標準時間的偏移量 NSInteger interval = [zone secondsFromGMTForDate: date]; NSLog(@quot;interval = %luquot;, interval); // 在當前時間基礎上追加時區差值 now = [now dateByAddingTimeInterval:interval]; NSLog(@quot;%@quot;, date);
6.2格式化日期
- NSDate -gt; NSString
// 1.創建時間 NSDate *now = [NSDate date]; // 2.創建時間格式化 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; // 3.指定格式 formatter.dateFormat = @quot;yyyy-MM-dd HH:mm:ssquot;; // 4.格式化時間 NSString *str = [formatter stringFromDate:now]; NSLog(@quot;%@quot;, str);
- NSString -gt; NSDate
NSString *str = @quot;2015-06-28 19:53:24quot;; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = @quot;yyyy-MM-dd HH:mm:ssquot;; NSDate *date = [formatter dateFromString:str]; NSLog(@quot;%@quot;, date);
6.3日期時間對象
- 結合NSCalendar和NSDate能做更多的日期\時間處理
- 獲得NSCalendar對象
NSCalendar *calendar = [NSCalendar currentCalendar];
- 獲得年月日
``` - (NSDateComponents )components:(NSCalendarUnit)unitFlags fromDate:(NSDate )date;
`` NSDate *date = [NSDate date]; // 1.創建日歷對象 NSCalendar *calendar = [NSCalendar currentCalendar]; // 2.利用日歷對象獲取年月日時分秒 NSCalendarUnit type = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; NSDateComponents *cmps =[calendar components:type fromDate:date]; NSLog(@quot;year = %luquot;, cmps.year); NSLog(@quot;month = %luquot;, cmps.month); NSLog(@quot;day = %luquot;, cmps.day); NSLog(@quot;hour = %luquot;, cmps.hour); NSLog(@quot;minute = %luquot;, cmps.minute); NSLog(@quot;second = %luquot;, cmps.second); NSLog(@quot;date = %@quot;, date);
- 比較兩個日期的差距
- (NSDateComponents *)components:(NSCalendarUnit)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSCalendarOptions)opts;
// 1.確定時間 NSString *time1 = @quot;2015-06-23 12:18:15quot;; NSString *time2 = @quot;2015-06-28 10:10:10quot;; // 2.將時間轉換為 date NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.dateFormat = @quot;yyyy-MM-dd HH:mm:ssquot;; NSDate *date1 = [formatter dateFromString:time1]; NSDate *date2 = [formatter dateFromString:time2]; // 3.創建日歷 NSCalendar *calendar = [NSCalendar currentCalendar]; NSCalendarUnit type = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; // 4.利用日歷對象比較兩個時間的差值 NSDateComponents *cmps = [calendar components:type fromDate:date1 toDate:date2 options:0]; // 5.輸出結果 NSLog(@quot;兩個時間相差%ld年%ld月%ld日%ld小時%ld分鐘%ld秒quot;, cmps.year, cmps.month, cmps.day, cmps.hour, cmps.minute, cmps.second);
七、NSFileManager
7.1NSFileManager介紹
- 什么是NSFileManager
- 顧名思義, NSFileManager是用來管理文件系統的
- 它可以用來進行常見的文件\文件夾操作
- NSFileManager使用了單例模式
- 使用defaultManager方法可以獲得那個單例對象
[NSFileManager defaultManager]
- 使用defaultManager方法可以獲得那個單例對象
- NSFileManager用法
- -(BOOL)fileExistsAtPath:(NSString *)path;
- path這個文件\文件夾是否存在
NSFileManager *manager = [NSFileManager defaultManager]; // 可以判斷文件 BOOL flag = [manager fileExistsAtPath:@quot;/Users/LNJ/Desktop/lnj.txtquot;]; NSLog(@quot;flag = %iquot;, flag); // 可以判斷文件夾 flag = [manager fileExistsAtPath:@quot;/Users/LNJ/Desktop/未命名文件夾quot;]; NSLog(@quot;flag = %iquot;, flag);
- path這個文件\文件夾是否存在
- -(BOOL)fileExistsAtPath:(NSString )path isDirectory:(BOOL )isDirectory;
- path這個文件\文件夾是否存在, isDirectory代表是否為文件夾
NSFileManager *manager = [NSFileManager defaultManager]; BOOL directory = NO; BOOL flag = [manager fileExistsAtPath:@quot;/Users/LNJ/Desktop/未命名文件夾quot; isDirectory:amp;directory]; NSLog(@quot;flag = %i, directory = %iquot;, flag, directory);
- path這個文件\文件夾是否存在, isDirectory代表是否為文件夾
- -(BOOL)isReadableFileAtPath:(NSString *)path;
- path這個文件\文件夾是否可讀
- -(BOOL)isWritableFileAtPath:(NSString *)path;
- path這個文件\文件夾是否可寫
- 系統目錄不允許寫入
- -(BOOL)isDeletableFileAtPath:(NSString *)path;
- path這個文件\文件夾是否可刪除
- 系統目錄不允許刪除
7.3NSFileManager的文件訪問
- -(NSDictionary )attributesOfItemAtPath:(NSString )path error:(NSError **)error;
- 獲得path這個文件\文件夾的屬性
NSFileManager *manager = [NSFileManager defaultManager]; NSDictionary *dict = [manager attributesOfItemAtPath:@quot;/Users/LNJ/Desktop/lnj.txtquot; error:nil]; NSLog(@quot;dit = %@quot;, dict);
- 獲得path這個文件\文件夾的屬性
- -(NSArray )contentsOfDirectoryAtPath:(NSString )path error:(NSError **)error;
- 獲得path的當前子路徑
- -(NSData )contentsAtPath:(NSString )path;
- 獲得文件內容
NSFileManager *manager = [NSFileManager defaultManager]; NSArray *paths = [manager contentsOfDirectoryAtPath:@quot;/Users/LNJ/Desktop/quot; error:nil]; NSLog(@quot;paths = %@quot;, paths);
- 獲得文件內容
- -(NSArray )subpathsAtPath:(NSString )path;
- -(NSArray )subpathsOfDirectoryAtPath:(NSString )path error:(NSError **)error; - 獲得path的所有子路徑
NSFileManager *manager = [NSFileManager defaultManager]; NSArray *paths = [manager subpathsAtPath:@quot;/Users/LNJ/Desktop/quot;]; NSLog(@quot;paths = %@quot;, paths);
7.4NSFileManager的文件操作
- -(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;
- 創建文件夾(createIntermediates為YES代表自動創建中間的文件夾)
NSFileManager *manager = [NSFileManager defaultManager]; BOOL flag = [manager createDirectoryAtPath:@quot;/Users/LNJ/Desktop/testquot; withIntermediateDirectories:YES attributes:nil error:nil]; NSLog(@quot;flag = %iquot;, flag);
- 創建文件夾(createIntermediates為YES代表自動創建中間的文件夾)
- -(BOOL)createFileAtPath:(NSString )path contents:(NSData )data attributes:(NSDictionary *)attr;
- 創建文件(NSData是用來存儲二進制字節數據的)
NSString *str = @quot;lnjquot;; NSData *data = http://www.tuicool.com/articles/[str dataUsingEncoding:NSUTF8StringEncoding]; NSFileManager *manager = [NSFileManager defaultManager]; BOOL flag = [manager createFileAtPath:@quot;/Users/LNJ/Desktop/abc.txtquot; contents:data attributes:nil]; NSLog(@quot;flag = %iquot;, flag);
- 創建文件(NSData是用來存儲二進制字節數據的)
八、集合對象的內存管理
8.1集合對象的內存管理
- 當一個對象加入到集合中,那么該對象的引用計數會 1
- 當集合被銷毀的時候,集合會向集合中的元素發送release消息
NSMutableArray *arr = [[NSMutableArray alloc] init]; Person *p = [[Person alloc] init]; NSLog(@quot;retainCount = %luquot;, [p retainCount]); [arr addObject:p]; NSLog(@quot;retainCount = %luquot;, [p retainCount]); [p release]; NSLog(@quot;retainCount = %luquot;, [p retainCount]); [arr release];
- 當一個對象加入到集合中,那么該對象的引用計數會 1
- 當把一個對象從集合中移除時,會向移除的元素發送release消息
NSMutableArray *arr = [[NSMutableArray alloc] init]; Person *p = [[Person alloc] init]; NSLog(@quot;retainCount = %luquot;, [p retainCount]); [arr addObject:p]; NSLog(@quot;retainCount = %luquot;, [p retainCount]); [arr removeObject:p]; NSLog(@quot;retainCount = %luquot;, [p retainCount]); [p release]; [arr release];
8.2集合對象內存管理總結
- 1.官方內存管理原則
- 1gt; 當調用alloc、new、copy(mutableCopy)方法產生一個新對象的時候,就必須在最后調用一次release或者autorelease
- 2gt; 當調用retain方法讓對象的計數器 1,就必須在最后調用一次release或者autorelease
- 2.集合的內存管理細節
- 1gt; 當把一個對象添加到集合中時,這個對象會做了一次retain操作,計數器會 1
- 2gt; 當一個集合被銷毀時,會對集合里面的所有對象做一次release操作,計數器會-1
- 3gt; 當一個對象從集合中移除時,這個對象會一次release操作,計數器會-1
- 3.普遍規律
- 1gt; 如果方法名是add\insert開頭,那么被添加的對象,計數器會 1
- 2gt; 如果方法名是remove\delete開頭,那么被移除的對象,計數器-1
九、Copy
9.1copy基本概念
- 什么是copy
- Copy的字面意思是“復制”、“拷貝”,是一個產生副本的過程
- 常見的復制有:文件復制
- 作用:利用一個源文件產生一個副本文件
- 特點:
- 修改源文件的內容,不會影響副本文件
- 修改副本文件的內容,不會影響源文件
- OC中的copy
- 作用:利用一個源對象產生一個副本對象
- 特點:修改源對象的屬性和行為,不會影響副本對象
- 修改副本對象的屬性和行為,不會影響源對象
9.2Copy的使用
- 如何使用copy功能
- 一個對象可以調用copy或mutableCopy方法來創建一個副本對象
-copy : 創建的是不可變副本(如NSString、NSArray、NSDictionary) - mutableCopy :創建的是可變副本(如NSMutableString、NSMutableArray、NSMutableDictionary)
- 一個對象可以調用copy或mutableCopy方法來創建一個副本對象
- 使用copy功能的前提
- copy : 需要遵守NSCopying協議,實現copyWithZone:方法
@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
- 使用mutableCopy的前提
- 需要遵守NSMutableCopying協議,實現mutableCopyWithZone:方法
@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
9.2深復制和淺復制
- 淺復制(淺拷貝,指針拷貝,shallow copy)
- 源對象和副本對象是同一個對象
- 源對象(副本對象)引用計數器 1,相當于做一次retain操作
- 本質是:沒有產生新的對象
NSString *srcStr = @quot;lnjquot;; NSString *copyStr = [srcStr copy]; NSLog(@quot;src = http://www.tuicool.com/articles/%p, copy = %pquot;, srcStr, copyStr);
-
深復制(深拷貝,內容拷貝,deep copy)
- 源對象和副本對象是不同的兩個對象
- 源對象引用計數器不變,副本對象計數器為1(因為是新產生的)
- 本質是:產生了新的對象
NSString *srcStr = @quot;lnjquot;; NSMutableString *copyStr = [srcStr mutableCopy]; NSLog(@quot;src = http://www.tuicool.com/articles/%p, copy = %pquot;, srcStr, copyStr); NSLog(@quot;src = %@, copy = %@quot;, srcStr, copyStr); [copyStr appendString:@quot; coolquot;]; NSLog(@quot;src = %@, copy = %@quot;, srcStr, copyStr);
NSMutableString *srcStr = [NSMutableString stringWithFormat:@quot;lnjquot;]; NSString *copyStr = [srcStr copy]; [srcStr appendString:@quot; coolquot;]; NSLog(@quot;src = http://www.tuicool.com/articles/%p, copy = %pquot;, srcStr, copyStr); NSLog(@quot;src = %@, copy = %@quot;, srcStr, copyStr);
NSMutableString *srcStr = [NSMutableString stringWithFormat:@quot;lnjquot;]; NSMutableString *copyStr = [srcStr mutableCopy]; [srcStr appendString:@quot; coolquot;]; [copyStr appendString:@quot; 520itquot;]; NSLog(@quot;src = http://www.tuicool.com/articles/%p, copy = %pquot;, srcStr, copyStr); NSLog(@quot;src = %@, copy = %@quot;, srcStr, copyStr);
-
只有源對象和副本對象都不可變時,才是淺復制,其它都是深復制
Paste_Image.png
十、copy與內存管理
10.1copy與內存管理
- 淺拷貝
- 原對象引用計數器 1
- 必須對原對象進行釋放
har *cstr = quot;this is a c stringquot;; NSString *str1 = [[NSString alloc] initWithUTF8String:cstr]; NSLog(@quot;str = %luquot;, [str1 retainCount]); NSString *str2 = [str1 copy]; NSLog(@quot;str = %luquot;, [str1 retainCount]); [str2 release];必須做一次release
- 深拷貝
- 必須釋放新對象
char *cstr = quot;this is a c stringquot;; NSString *str1 = [[NSString alloc] initWithUTF8String:cstr]; NSLog(@quot;str = %luquot;, [str1 retainCount]); NSMutableString *str2 = [str1 mutableCopy]; NSLog(@quot;str = %luquot;, [str1 retainCount]); [str2 release]; // 必須做一次release
- 必須釋放新對象
十一、property中的copy關鍵字
11.1@property中的copy的作用
- 防止外界修改內部的值
@interface Person : NSObject @property (nonatomic, retain) NSString *name; @end
NSMutableString *str = [NSMutableString stringWithFormat:@quot;lnjquot;]; Person *p = [[Person alloc] init]; p.name = str; // person中的屬性會被修改 [str appendString:@quot; coolquot;]; NSLog(@quot;name = %@quot;, p.name);
- 防止訪問對象對象已經釋放
- 不用copy情況
Person *p = [[Person alloc] init]; p.name = @quot;lnjquot;; Dog *d = [[Dog alloc] init]; d.age = 10; NSLog(@quot;retainCount = %luquot;, [d retainCount]);// 1 p.pBlock = ^{ // 報錯, 調用之前就銷毀了 NSLog(@quot;age = %dquot;, d.age); }; [d release]; // 0 p.pBlock(); [p release];
- 用copy情況
Person *p = [[Person alloc] init]; p.name = @quot;lnjquot;; Dog *d = [[Dog alloc] init]; d.age = 10; NSLog(@quot;retainCount = %luquot;, [d retainCount]); // 1 p.pBlock = ^{ // 會對使用到的外界對象進行一次retain NSLog(@quot;age = %dquot;, d.age); NSLog(@quot;retainCount = %luquot;, [d retainCount]); // 1 }; [d release]; // 1 p.pBlock(); [p release];
- 不用copy情況
11.2@property內存管理策略選擇
-
非ARC
- 1gt; copy : 只用于NSString\block
- 2gt; retain : 除NSString\block以外的OC對象
- 3gt; assign :基本數據類型、枚舉、結構體(非OC對象),當2個對象相互引用,一端用retain,一端用assign
-
ARC
- 1gt; copy : 只用于NSString\block
- 2gt; strong : 除NSString\block以外的OC對象
- 3gt; weak : 當2個對象相互引用,一端用strong,一端用weak
- 4gt; assgin : 基本數據類型、枚舉、結構體(非OC對象)
十二、自定義的類實現copy操作
12.1自定義類實現copy操作
- 讓類遵守NSCopying協議
- 實現 copyWithZone:方法,在該方法中返回一個對象的副本即可。
-
在copyWithZone方法中,創建一個新的對象,并設置該對象的數據與現有對象一致, 并返回該對象.
zone: 表示空間,分配對象是需要內存空間的,如果指定了zone,就可以指定 新建對象對應的內存空間。但是:zone是一個非常古老的技術,為了避免在堆中出現內存碎片而使用的。在今天的開發中,zone幾乎可以忽略
-
無父類實現
-(id)copyWithZone(NSZone *)zone{ CustomMode *custom = [[[self class] copyWithZone:zone] init]; Custom -gt;_a = [_a copyWithZone:zone]; Custom -gt; _c = _c;//不是對象的 直接賦值 Return custom; }
- 有父類實現
- 不調用父類方法, 無法拷貝父類中繼承的屬性
- 不重新父類copyWithZone, 無法拷貝本來中的特有屬性
-(id)copyWithZone(NSZone *)zone{ CustomModel *custom = [super copyWithZone:zone]; …. Return custom; }
十三、單例設計模式
13.1單例模式概念
- 什么是單例模式:(辛格爾頓)
- 單例模式的意圖是是的類的對象成為系統中唯一的實例,#56319;#56320;供一個訪問點,供客戶類共享資源。
- 什么情況下使用單例?
- 1,類只能有一個實例,而且必須從一個為人熟知的訪問點對其進行訪問,比如工廠方法。
- 2,這個唯一的實例只能通過子類化進行擴展,而且擴展的對象不會破壞客戶端代碼。
- 單例設計模式的要點:
- (1)某個類只能有一個實例。
- (2)他必須自行創建這個對象
- (3)必須自行向整個系統#56319;#56320;供這個實例;
- (4)為了保證實例的唯一性,我們必須將
- (5)這個方法必須是一個靜態類
13.2簡單的單例模式實現
#define interfaceSingleton(name) (instancetype)share##name #if __has_feature(objc_arc) // ARC (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(amp;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(amp;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
代碼鏈接
百度云:
鏈接: https://pan.baidu.com/s/1eSx9GT8 密碼: p4fp
Tags: NSDictionary
文章來源:http://www.jianshu.com/p/77431ccf15ac