前段時(shí)間忙了一陣,終于靜下心來(lái)補(bǔ)作業(yè)了吩跋,先把第二周的學(xué)習(xí)筆記補(bǔ)上寞射。
這周主要學(xué)習(xí)的是字符串、集合這兩個(gè)OC中非常重要的類型锌钮,使用自動(dòng)引用計(jì)數(shù)ARC(Automatic Reference Counting)管理對(duì)象的創(chuàng)建和釋放桥温,以及利用協(xié)議(protocols)約定類的行為和利用類別(categories)和擴(kuò)展(extensions)來(lái)定制一個(gè)類。
字符串
字符串在OC中如何處理梁丘?
一個(gè)字符串在OC中常常是字符串類(NSString)的一個(gè)實(shí)例侵浸。
而像int, float and char這樣的C當(dāng)中的純量數(shù)據(jù)類型旺韭,則儲(chǔ)存于純量的本地變量或者屬性中。
While strings of characters are usually represented as instances of the NSString class, numeric values are often stored in scalar local variables or properties.
創(chuàng)建字符串對(duì)象(NSString)掏觉?
可以用三種方法:
1.字面量初始化literal syntax
NSString *thirdString = @"Hello World!";
2.初始化器
NSString *firstString = [[NSString alloc] initWithCString:"HelloWorld!"?encoding:NSUTF8StringEncoding];
3.工廠化方法
NSString *secondString = [NSString stringWithCString:"HelloWorld!"?encoding:NSUTF8StringEncoding];
NSString和NSMutableSting区端?
NSMutableString是NSString的子類。他們的主要區(qū)別是:
The basic NSString class is immutable, which means its contents are set at creation and cannot later be changed. If you need to represent a different string, you must create a new string object //NSString在創(chuàng)建后內(nèi)容就不可更改澳腹,如果要得到一個(gè)不同的字符串织盼,我們就只能重新創(chuàng)建一個(gè)新的字符串對(duì)象。
The NSMutableString class is the mutable subclass of NSString, and allows you to change its character contents at runtime using methods like appendString: or appendFormat: //NSMutableString可以在創(chuàng)建后更改字符內(nèi)容酱塔。
這一NSString的重要特性稱為恒定性(immutable)沥邻。
NSString的另一個(gè)特性稱為共享性:
NSString * str1 = @"Hello World!";
NSString * str4 = @"Hello World!";
//通過(guò)共享性,在實(shí)際運(yùn)行時(shí)這兩個(gè)字符串對(duì)象的內(nèi)容會(huì)指向同一個(gè)指針羊娃。這樣避免了當(dāng)一個(gè)程序中具有多個(gè)"Hello World!"對(duì)象時(shí)造成的內(nèi)存空間浪費(fèi)唐全。
//然而,只有通過(guò)像上述這樣蕊玷,字面量初始化literal syntax創(chuàng)建的NSString字符串才具有這一特性
NSMutableString沒(méi)有共享性邮利。
NSMutableString相比NSString還是多了很多字符串操作,像添加垃帅、刪除和修改字符串近弟。值得注意的是,在修改字符串時(shí)挺智,如果需求祷愉,NSMutableString不是在原有內(nèi)存上直接增長(zhǎng),而是重新分配一個(gè)更大或者更小的內(nèi)存容量來(lái)存放字符赦颇。
所以一個(gè)實(shí)用的技巧是二鳄,估計(jì)好NSMutableString的capacity,預(yù)先分配好一定容量媒怯,避免以后capacity的增長(zhǎng):
NSMutableString *mustr3 =[NSMutableString stringWithCapacity:100]; //創(chuàng)建一個(gè)capacity為100的NSMutableString
集合
OC中絕大多數(shù)的集合都是對(duì)象订讼,如數(shù)組(NSArray)、Set(NSSet)扇苞、Dictionary(NSDictionary)欺殿。
并且,集合中的元素必須是對(duì)象:
These classes are used to manage groups of objects, which means any item you wish to add to a collection must be an instance of an Objective-C class. If you need to add a scalar value, you must first create a suitable NSNumber or NSValue instance to represent it.//如果是純量元素鳖敷,我們需要首先創(chuàng)建一個(gè)合適的NSNumber或者NSValue實(shí)例來(lái)表達(dá)它們脖苏。
所有這些集合都支持對(duì)元素的遍歷(enumeration)、查找(finding out whether a particular object is part of the collection)和訪問(wèn)(accessing specific items)定踱。
所有三個(gè)集合都具有常量性(immutable):不可以更改元素長(zhǎng)度棍潘、不可以更改元素指針、可以更改指針指向的內(nèi)容。
和字符串類類似亦歉,它們對(duì)應(yīng)的可變集合分別是可變數(shù)組(NSMutableArray)恤浪、可變Set(NSMutableSet)、可變Dictionary(NSMutableDictionary)肴楷。
集合的遍歷有三種方法:
1.Fast Enumeration快速枚舉水由,最快
for (<Type> <variable> in <collection>) {
...
} ?//Fast Enumeration
2.NSEnumeration迭代器模式,較慢
3.for循環(huán)赛蔫,最慢砂客,如果沒(méi)有非用不可的情況不使用
for (<#initialization#>; <#condition#>; <#increment#>) {
<#statements#>
}
ARC
ARC(Automatic Reference Counting)自動(dòng)引用計(jì)數(shù),是OC默認(rèn)的內(nèi)存管理機(jī)制濒募,針對(duì)的是堆上的對(duì)象,由編譯器自動(dòng)生成操作引用計(jì)數(shù)的指令(retain或release),來(lái)管理對(duì)象的創(chuàng)建與釋放圾结。
哪些對(duì)象受ARC管理:
OC對(duì)象指針
Block指針
使用__attribute__((NSObject))定義的typedef
哪些對(duì)象不受ARC管理:
值類型
使用其他方式分配的堆對(duì)象(如使用malloc分配)
非內(nèi)存資源
自動(dòng)釋放池(autorelease)
對(duì)象的釋放延遲到自動(dòng)釋放池被釋放時(shí) ?
自動(dòng)釋放池Block的使用是推薦的瑰剃,當(dāng)其結(jié)束時(shí),所有接受autorelease消息的對(duì)象將會(huì)被立即釋放筝野。避免對(duì)內(nèi)存的瑣碎管理晌姚。
APP KIT/UIKIT的事件處理,會(huì)自動(dòng)使用autorelease pool歇竟,所以大多數(shù)情況無(wú)需程序員手工干預(yù)挥唠。
協(xié)議
只提供外部接口,不提供具體實(shí)現(xiàn)焕议。
協(xié)議可以包含以下成員:
屬性
實(shí)例方法
類方法
初始化器和析構(gòu)器(不常用)
協(xié)議不可以包含:
實(shí)例變量成員
協(xié)議內(nèi)成員默認(rèn)具有@required屬性宝磨,必須實(shí)現(xiàn)。
可選成員寫在@optional語(yǔ)句之后盅安,可以選擇實(shí)現(xiàn)唤锉。
實(shí)現(xiàn)語(yǔ)句在具體遵循協(xié)議的類的實(shí)現(xiàn)中編寫。
如捕魚器類(FishTrapper)遵循捕撈協(xié)議(Trapping):
@interface FishTrapper:NSObject<Trapping> ? ? //捕魚器類是實(shí)現(xiàn)類
@property NSInteger n; ? ? ? ? ? ? ? ? ? ?//實(shí)現(xiàn)類中需要聲明協(xié)議類中的屬性别瞭,因?yàn)閰f(xié)議自身不能合成實(shí)例變量窿祥,需要實(shí)現(xiàn)類在編譯中合成。
@property NSMutableArray * array; ?//同上蝙寨,這是一個(gè)實(shí)現(xiàn)類中聲明的協(xié)議屬性
@end
Trapping類只具有h文件:
@protocol Trapping ? ? ? ? ? ? ? ? ? ? ? ? ? ?//捕撈是協(xié)議類
@property NSInteger n; ? ? ? ? ? ? ? ? ? ? ? //捕撈類中的屬性
@property NSMutableArray * array; ? ? //捕撈類中的屬性
//@required
-(void)trapFishInArray:(NSMutableArray *)array withN:(NSInteger)n; ?//協(xié)議中的實(shí)例方法
@end
以上兩個(gè)類聲明的屬性晒衩、方法等成員需要在實(shí)現(xiàn)類——捕魚器類(FishTrapper)的implementation(m文件)中實(shí)現(xiàn):
@implementation FishTrapper : NSObject
-(id)init{
...省略
}
-(void)trapFishInArray:(NSMutableArray *)array withN:(NSInteger)n{
...省略
}
@end
檢查對(duì)象是否實(shí)現(xiàn)了協(xié)議用conformsToProtocol:
類的定制
使用類別(category)可以為類添加方法(無(wú)源代碼情況)。
以NSMutableArray類為例墙歪,如果我們想讓它更好地服務(wù)于我的Animal項(xiàng)目听系,給它添加一個(gè)enumerateArrayAnimal方法:
@interface NSMutableArray (AnimalEnumerateAdditions)
-(void)enumerateArrayAnimal;
@end
實(shí)現(xiàn):
@implementation NSMutableArray (AnimalEnumerateAdditions)
-(void)enumerateArrayAnimal{
...省略
}
@end
各自的文件命名規(guī)則:
NSMutableArray+AnimalEnumerateAdditions.h/.m ? ? ? ? ?//類名+類別名.h/.m
而在編譯時(shí)、有源代碼情況虹菲,可以用擴(kuò)展(extensions)向類添加功能跛锌,它可以被看作是匿名的類別。
擴(kuò)展支持添加以下成員:
添加屬性
添加實(shí)例成員
添加類方法
添加實(shí)例方法
改寫屬性的讀寫屬性
由于是匿名類別,擴(kuò)展的接口屬性在m文件的@implementation前聲明髓帽,實(shí)現(xiàn)代碼依然在@implementation中實(shí)現(xiàn)菠赚。
最后作業(yè)中的錯(cuò)題
主要是在捕撈協(xié)議中修改動(dòng)物數(shù)組時(shí)用FastEnumeration始終報(bào)錯(cuò)NSGenericException。
查了一下不能夠在for in循環(huán)中修改所遍歷的數(shù)組郑藏,無(wú)論是add或remove都不可以衡查,如果要修改的話,可以用for(;;;)格式必盖。