一哄尔、關(guān)鍵字
1假消、iOS中定義屬性/變量的修飾關(guān)鍵字
在聲明@property屬性/變量時(shí),總說(shuō)要在括號(hào)中寫(xiě)上assign岭接、retain富拗、copy、weak鸣戴、strong啃沪。
assign
assign 一般用來(lái)修飾基礎(chǔ)數(shù)據(jù)類型(NSInterger、CGF lost葵擎、int谅阿、float、double酬滤、char等)。
因?yàn)閍ssign聲明的屬性不會(huì)增加引用計(jì)數(shù)寓涨,屬性釋放后就沒(méi)有了盯串。若assign修飾的指針指向的是一個(gè)對(duì)象類型,被指向的對(duì)象dealloc后戒良,對(duì)象的這個(gè)指針還在体捏,被調(diào)用時(shí)就會(huì)crash。
所以一般只用來(lái)聲明基本數(shù)據(jù)類型糯崎,因?yàn)樗麄儠?huì)被分配到棧上几缭,而棧區(qū)會(huì)由系統(tǒng)自動(dòng)處理,不會(huì)造成野指針沃呢。
retain
與assign相對(duì)年栓,retain聲明后到對(duì)象會(huì)更改引用計(jì)數(shù)
對(duì)象被引用,引用計(jì)數(shù)+1薄霜。
釋放后某抓,引用計(jì)數(shù)-1。
即使這個(gè)對(duì)象本身釋放了惰瓜,只要還有對(duì)象引用它否副,就會(huì)被持有。
只有當(dāng)引用計(jì)數(shù)為0時(shí)崎坊,才被dealloc析構(gòu)函數(shù)回收备禀。
copy
最常見(jiàn)的是使用copy來(lái)修飾NSString.
copy 和 retain 的區(qū)別在于 retain 的引用是拷貝指針地址,而copy是拷貝的對(duì)象本人,也就是retain 是淺復(fù)制曲尸,copy是深復(fù)制呻待。
淺拷貝:當(dāng)修改對(duì)象值時(shí),都會(huì)被修改队腐;
深拷貝:修改對(duì)象值時(shí)蚕捉,不會(huì)引起其他使用對(duì)象;
淺拷貝:指針拷貝柴淘,對(duì)一個(gè)對(duì)象進(jìn)行淺拷貝迫淹,相當(dāng)于對(duì)只想這個(gè)對(duì)象的指針進(jìn)行拷貝,產(chǎn)生了一個(gè)新的指向這個(gè)對(duì)象的指針为严,那么就是有兩個(gè)指針同時(shí)指向同一個(gè)對(duì)象敛熬,這個(gè)對(duì)象銷毀后兩個(gè)指針都應(yīng)該置為空。 對(duì)象引用計(jì)數(shù)+1第股,相當(dāng)于進(jìn)行了一個(gè)retain操作应民。
深拷貝:內(nèi)容拷貝,相當(dāng)于對(duì)象進(jìn)行復(fù)制夕吻,產(chǎn)生一個(gè)新的對(duì)象诲锹,那么就有兩個(gè)指針?lè)謩e指向兩個(gè)對(duì)象,對(duì)一個(gè)對(duì)象的操作不會(huì)影響到另一個(gè)對(duì)象涉馅。copy屬性特性新的對(duì)象的引用計(jì)數(shù)為1归园,和舊有對(duì)象的引用計(jì)數(shù)無(wú)關(guān),舊對(duì)象沒(méi)有變化稚矿。
只有不可變對(duì)象創(chuàng)建不可變副本才是淺處之庸诱,其他都是深復(fù)制。
copy和mutablecopy存在的原因:盡可能的節(jié)省內(nèi)存開(kāi)銷晤揣。
**copy和mutableCopy方法
之所以在NSString這類可有可變類型的對(duì)象上使用桥爽,是因?yàn)樗麄冇锌赡芎蛯?duì)應(yīng)的可變類型(NSM unable String)之間進(jìn)行賦值操作,為了防止內(nèi)容改變昧识,使用copy去深復(fù)制一份钠四。
copy工作由copy方法執(zhí)行,此屬性只對(duì)那些實(shí)現(xiàn)了NSCo ping協(xié)議的對(duì)象類型有效滞诺。
assign 形导、retain、copy 可以在MRC中使用习霹,但是weak和strong就智能在ARC中使用朵耕,也就是自動(dòng)引用計(jì)數(shù),這時(shí)就不能手動(dòng)的去retain淋叶、release等操作了阎曹,ARC會(huì)幫我們完成這些工作。
weak
weak類似于assign,叫做弱引用处嫌。不會(huì)增加引用計(jì)數(shù)栅贴。在防止循環(huán)引用時(shí)使用(循環(huán)引用:父類引用了子類,子類又去引用父類)熏迹。IBOutlet檐薯、Delegate一般用的都是weak,這時(shí)因?yàn)樗麄冊(cè)陬惖耐獠勘徽{(diào)用注暗,防止循環(huán)引用坛缕。
strong
相對(duì)的,strong就類似于retain了捆昏,叫強(qiáng)引用赚楚,會(huì)增加引用計(jì)數(shù),類內(nèi)部使用的屬性一般都是strong修飾的骗卜,現(xiàn)在ARC已經(jīng)基本代替了MRC宠页,所以我門(mén)最常見(jiàn)的就是strong。
nonatomic
在定義屬性時(shí)寇仓,括號(hào)內(nèi)往往還會(huì)加一個(gè)nonatomic,它的名字叫做非原子訪問(wèn)举户。對(duì)應(yīng)的有atomic,是原子性的訪問(wèn)焚刺。如果一個(gè)屬性是由atomic修飾的敛摘,那么系統(tǒng)就會(huì)進(jìn)行線程保護(hù),防止多個(gè)寫(xiě)操作同時(shí)進(jìn)行乳愉。也有壞處:那就是消耗系統(tǒng)資源。所以對(duì)于iPhone這種移動(dòng)個(gè)設(shè)備屯远,如果不是進(jìn)行多線程的寫(xiě)操作蔓姚,就可以使用nonatomic,取消線程保護(hù)來(lái)提高性能。
二慨丐、block外部weak和內(nèi)部strong防止循環(huán)引用
大家都看到別人在block里面使用self或者self屬性的時(shí)候要使用__weak修飾坡脐,然后才能在block里面使用,在block里面使用的時(shí)候又將weakself使用__strong 修飾進(jìn)行使用房揭,比如:
__weak __typeof(self) weakSelf<wbr> = self;
self.block = ^{
__strong __typeof(self) strongSelf = weakSelf;
[strongSelf doSomeThing];
[strongSelf doOtherThing];
};
為什么要使用weakSelf修飾self
通過(guò)clang- rewrite- objc源代碼文件名將代碼轉(zhuǎn)為c++代碼(實(shí)際是c代碼)备闲,可以看到block是一個(gè)結(jié)構(gòu)體,它會(huì)將全局變量保存為一個(gè)屬性(是__strong修飾的)捅暴,而self強(qiáng)引用了block恬砂,這會(huì)造成循環(huán)引用。所以需要使用__weak修飾self蓬痒。
為什么在block里面需要使用strongSelf
是為了保證block執(zhí)行完畢之前self不會(huì)被釋放泻骤,執(zhí)行完畢的時(shí)候再釋放。這時(shí)候會(huì)發(fā)現(xiàn)為什么在block外面使用了__weak修飾self,里面使用__strong修飾weak self的時(shí)候不會(huì)發(fā)生循環(huán)引用狱掂。另外演痒,strong Self值時(shí)為了保證在block內(nèi)部執(zhí)行的時(shí)候不會(huì)被釋放,但存在執(zhí)行前self就已經(jīng)被釋放的情況趋惨,導(dǎo)致strongself=nil鸟顺。注意判空處理。
不會(huì)引起循環(huán)引用的原因
因?yàn)閎lock截獲self之后器虾,self屬于block結(jié)構(gòu)體中的一個(gè)由__strong修飾的屬性會(huì)強(qiáng)引用self讯嫂,所以需要使用__weak修飾self防止循環(huán)引用。block使用__strong修飾weakself是為了在block(可以理解為函數(shù))生命周期中self不會(huì)提前釋放曾撤。strong Self實(shí)質(zhì)是一個(gè)局部變量(在block這個(gè)函數(shù)里面的局部變量)端姚,當(dāng)block執(zhí)行完畢就會(huì)釋放自動(dòng)變量strongSelf,不會(huì)對(duì)self進(jìn)行一直強(qiáng)引用。
三挤悉、isa指針和imp指針
isa指針 是一個(gè)指向所屬類的指針渐裸,它標(biāo)注著一個(gè)實(shí)例對(duì)象的真實(shí)類型。
在object-c中消息機(jī)制是依靠 objc_msgSend()這個(gè)函數(shù)發(fā)送的装悲。
在objc_msgSend中昏鹃,包含兩個(gè)參數(shù):receiver、selector诀诊。即:objc_msgSend(receiver,selector);
而objc_msgSend通過(guò)isa指針洞渤,找到實(shí)例對(duì)象所屬的類,也就找到了其全部的類属瓣,如下圖所示:
一個(gè)方法被調(diào)用要經(jīng)過(guò)的步驟是:
當(dāng)我們向一個(gè)對(duì)象發(fā)送消息去調(diào)用它的方法時(shí):
msg_send會(huì)根據(jù)該實(shí)例對(duì)象的isa指針去查找該對(duì)象的類载迄,然后去查找該類的dispatch table中的selector。如果找不到就會(huì)一次向上查找它的父類抡蛙,并在其父類的dispatch table中查找selector护昧,直到查到基類NSObject。一旦找到selector粗截,object_msgSend會(huì)根據(jù)dispatch table中內(nèi)存地址去調(diào)用該selector惋耙。這樣實(shí)現(xiàn)message和selector在執(zhí)行階段的動(dòng)態(tài)綁定。為了提高查找轉(zhuǎn)發(fā)的效率熊昌,系統(tǒng)會(huì)把所有的selector內(nèi)存地址和調(diào)用過(guò)的selector的內(nèi)存地址緩存起來(lái)绽榛,通過(guò)類的形式劃分不同的緩存區(qū)域,沒(méi)個(gè)類的緩存區(qū)域會(huì)包括自己的selector和繼承自父類的selector婿屹,在objc_msgSend去查找dispatch table 前灭美,會(huì)先去檢查該類的緩存,如果緩存中有該selector选泻,就直接調(diào)用冲粤。
imp指針上指向selector具體實(shí)現(xiàn)的指針美莫。
在了解imp指針之前,來(lái)探討一個(gè)問(wèn)題梯捕,現(xiàn)在需求上在不影響層級(jí)結(jié)構(gòu)和盡量少改動(dòng)的情況下厢呵,讓項(xiàng)目中所有view controller的viewdidload方法中打印自己的類型,了解Runtime 的同學(xué)可能會(huì)想到 method_exchangeImplementation(Method m1,Method m2)
這種方式很輕松的實(shí)現(xiàn)了我門(mén)的需求傀顾,但是作為一個(gè)優(yōu)雅的程序要襟铭,就要做優(yōu)雅的事。下面就要用imp指針短曾。
首先寒砖,配置工程,進(jìn)行如下配置
配置完成直接上代碼
使用imp指針更改方法實(shí)現(xiàn)成功嫉拐。這樣做比上一種方式更加優(yōu)雅哩都。
接下來(lái)探討一下method_exchangeImplementation(Method m1,Method m2)方法的實(shí)現(xiàn)原理:
從imp指針的地址打印來(lái)看貌似這個(gè)方法是將兩個(gè)方法的imp指針做了互換。
經(jīng)過(guò)這么多代碼的測(cè)試婉徘,最終印證的還是那句話漠嵌,imp指針是指向selector具體實(shí)現(xiàn)的指針。
附加下真實(shí)imp的具體定義:
SEL:方法編號(hào)盖呼,根據(jù)方法編號(hào)就可以找到對(duì)應(yīng)方法實(shí)現(xiàn)儒鹿。
KVC
KVC 的全稱是KeyValueCoding, 俗稱“鍵值編碼”,可以通過(guò)一個(gè)key直接訪問(wèn)對(duì)象的屬性几晤,或者給對(duì)象的屬性賦值约炎。這樣可以在運(yùn)行時(shí)動(dòng)態(tài)的訪問(wèn)和修改對(duì)象的屬性。
常見(jiàn)的API
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (id)valueForKey:(NSString *)key;
key 和 keyPath 的區(qū)別
key:只能接受當(dāng)前類所具有的屬性蟹瘾,不管是自己的還是從父類繼承過(guò)來(lái)的圾浅。如:view.setValue(CGRectZero,key: "frame");
keyPath:除了能接受當(dāng)前類的屬性,還能接受當(dāng)前類屬性的屬性憾朴,即可以接受關(guān)系鏈贱傀,如:view.setVale(5,keyPath:"layer.cornerRadius");
KVC的原理:(賦值原理和取值原理)
KVC賦值原理:setValue:forKey:的原理
- 首先會(huì)按照setKey,_setKey的順序查找方法,找到方法伊脓,直接調(diào)用方法并賦值;
- 未找到方法魁衙,則調(diào)用+(BOOL)accessInstanceVariablesDirectly(是否可以直接訪問(wèn)成員變量报腔,默認(rèn)返回YES);
- 若accessInstanceVaariablesDirectly方法返回yes剖淀,則按照_key,_isKey,key,isKey的順序查找成員變量纯蛾,找到直接賦值,找不到則跑出NSUnknowKeyExpection異常纵隔;
-
若accessInstanceVariableDirecctly返回NO翻诉,那么就會(huì)調(diào)用setValue:forUnderfineKey:并跑出NSUnKnowKeyExpection異常炮姨;
KVC取值的原理:valueForKey:
-
首先會(huì)按照getKey,Key,isKey,_key的順序查找方法,找到直接調(diào)用取值碰煌;
-若未找到舒岸,則查看+(BOOL)accessInstanceVariableDirectly的返回值,若返回NO芦圾,則直接拋出NSUnkonwKeyExpection的異常蛾派;
-若返回的是YES,則按照_key,isKey的順序查找成員變量,找到則取值个少;
-若找不到則調(diào)用valueForUnderfineKey:拋出NSUnkonwKeyExpection異常洪乍;
注意
- key 的值必須正確,如果拼寫(xiě)錯(cuò)誤夜焦,則會(huì)出現(xiàn)異常壳澳。
- 當(dāng)key的值時(shí)沒(méi)有定義的,valueForUndefinedKey:這個(gè)方法會(huì)被調(diào)用茫经,如果你自己寫(xiě)了這個(gè)方法巷波,key的值出錯(cuò)就會(huì)調(diào)用到這里來(lái)。
- 因?yàn)轭惪梢苑磸?fù)嵌套科平,所以有個(gè)keyPath的概念褥紫,keyPath就是用 . (點(diǎn)語(yǔ)法) 來(lái)把key鏈接起來(lái),這樣就可以根據(jù)這個(gè)路徑訪問(wèn)下來(lái)瞪慧。
- NSArray/ NSSet等都支持KVC
- 可以通過(guò)KVC訪問(wèn)自定義類型的私有成員髓考。
- 如果對(duì)非對(duì)象傳遞一個(gè)nil值,KVC會(huì)調(diào)用setNilValueForKey方法弃酌,我們可以重寫(xiě)這個(gè)方法來(lái)避免傳遞nil出現(xiàn)的錯(cuò)誤氨菇,對(duì)象并不會(huì)調(diào)用這個(gè)方法,而是會(huì)直接報(bào)錯(cuò)妓湘。
- 處理非對(duì)象,setValue時(shí)查蓉,如果賦值的對(duì)象時(shí)基本類型,需要將值封裝成NSMNumber或者NSValue類型榜贴,valueForKey時(shí)豌研,返回的是id類型對(duì)象,基本數(shù)據(jù)類型也會(huì)被封裝成NSNumber或者NSValue唬党。 valueForKey可以自動(dòng)將值封裝成對(duì)象鹃共,但是setValue:forKey:卻不行。我門(mén)必須手動(dòng)將值轉(zhuǎn)換成NSNumber/NSValue類型才能進(jìn)行傳遞驶拱。
- 利用KVC進(jìn)行字典和模型的轉(zhuǎn)換
** KVO **
1.簡(jiǎn)單介紹
KVO全稱是KeyValueObserving, 俗稱“鍵值監(jiān)聽(tīng)”霜浴,可以用于監(jiān)聽(tīng)某個(gè)對(duì)象屬性值的改變。
KVO是平托提供的在套事件通知機(jī)制蓝纲。KVO和NSNotificationCenter都是IOS中的觀察者模式的一種實(shí)現(xiàn)阴孟,區(qū)別是NSNotificationCenter可以說(shuō)一對(duì)多的關(guān)系晌纫,而KVO說(shuō)是一對(duì)一的;
2.KVO的使用
2.1KVO的使用步驟:
注冊(cè)KVO監(jiān)聽(tīng):通過(guò)[addObserver:forKeyPath:options:context:]方法注冊(cè)KVO永丝,這樣可以接收到keyPath屬性的變化事件锹漱;
監(jiān)聽(tīng)的實(shí)現(xiàn):通過(guò)[observeValueForKeyPath:ofObject:chang:context]實(shí)現(xiàn)kvo的監(jiān)聽(tīng);
移除KVO監(jiān)聽(tīng):在不需要監(jiān)聽(tīng)的時(shí)候类溢,通過(guò)方法[removeObserver:forKeyPath:]移除監(jiān)聽(tīng)凌蔬;
2.2,KVO傳值
可以通過(guò)方法context傳入任意類型的對(duì)象,在接受消息回調(diào)的代碼中可以接收到這個(gè)對(duì)象闯冷,是KVO的一種傳值方式砂心。
可以通過(guò)KVO在Model和Controller之間進(jìn)行通信。
3.KVO的本質(zhì)是改變setter方法的調(diào)用:
- 1蛇耀、利用Runtime API動(dòng)態(tài)生成一個(gè)子類NSKVONotifying_XXX辩诞,并且讓instance對(duì)象的isa指針指向這個(gè)全新的子類,NSKVONotifying_XXX的super class指針指向原來(lái)的類纺涤;
- 2译暂、當(dāng)修改instance對(duì)象的屬性時(shí),會(huì)調(diào)用Foundation的_NSSetXXXValueAndNotify函數(shù):
Runtime
Runtime簡(jiǎn)稱 運(yùn)行時(shí)撩炊。 OC 就是運(yùn)行時(shí)機(jī)制外永,也就是把函數(shù)的調(diào)用推遲到運(yùn)行時(shí)。
Runtime的作用:
- 發(fā)送消息拧咳。
方法調(diào)用的本質(zhì)伯顶,就是讓對(duì)象發(fā)送消息。
obc_msgSend,只有對(duì)象才能發(fā)送消息骆膝,因此以objc開(kāi)頭
使用消息機(jī)制的前提祭衩,必須導(dǎo)入import<objc/message.h> - 交換方法
開(kāi)發(fā)使用場(chǎng)景:系統(tǒng)自帶的方法功能不夠,給系統(tǒng)自帶的方法擴(kuò)展一些功能阅签,并保持原有的功能掐暮。
方式一:繼承系統(tǒng)的類,重寫(xiě)方法政钟。
方式二:使用runtime路克,交換方法 - 動(dòng)態(tài)添加方法
開(kāi)發(fā)使用場(chǎng)景:如果一個(gè)類方法非常多,加載類到內(nèi)存的時(shí)候也比較耗費(fèi)資源养交,需要給每個(gè)方法生成映射表衷戈,可以使用動(dòng)態(tài)給某個(gè)類添加方法解決。 - 給分類添加屬性
原理:給一個(gè)類聲明屬性层坠,其實(shí)本質(zhì)就是給這個(gè)類添加關(guān)聯(lián),并不是直接把這個(gè)值的內(nèi)存空間添加到類存空間刁笙。
Runtime消息傳遞
一個(gè)對(duì)象的方法像這樣 [obj foo], 編譯器專程消息發(fā)送 objc_msgSend(obj, foo),Runtime時(shí)執(zhí)行的流程時(shí)這樣的:
- 首先破花,通過(guò)obj的isa指針找到它的class谦趣;
- 在class 的 method list 找到 foo;
- 如果class 中沒(méi)找到foo, 就繼續(xù)往它的superclass中找座每;
- 一旦找到foo這個(gè)函數(shù)前鹅,就去執(zhí)行它的實(shí)現(xiàn)的IMP;
但這種實(shí)現(xiàn)有個(gè)問(wèn)題峭梳,效率低舰绘。但一個(gè)class往往只有20%的函數(shù)會(huì)被經(jīng)常調(diào)用。每個(gè)消息都需要遍歷一次objc_method_list 并不合理葱椭,如果把經(jīng)常調(diào)用的函數(shù)緩存下來(lái)捂寿,就可以大大提高函數(shù)查詢的效率/這也就是objc_class中另一個(gè)重要的成員objc_cache要做的事情,在找到foo后孵运,把foo 的method_name作為key, method_imp作為value給存起來(lái)秦陋。當(dāng)再次收到foo消息的時(shí)候,可以直接在cache里找到治笨,避免去遍歷objc_method_list驳概。
分類和擴(kuò)展
1、分類主要為某個(gè)類添加方法旷赖、屬性顺又、協(xié)議(我一般為系統(tǒng)的類添加方法和把復(fù)雜的類按照功能拆到不同的文件中進(jìn)行解耦)
2、擴(kuò)展主要為某個(gè)類添加原來(lái)沒(méi)有的成員變量等孵、方法稚照、屬性。(我一般用擴(kuò)展來(lái)聲明私有屬性流济,或者把.h的只讀屬性重寫(xiě)成可讀)
區(qū)別:
- 分類是運(yùn)行時(shí)把類的信息合并到類中锐锣,擴(kuò)展是在編譯時(shí)把類的信息合并到類中。
- 分類聲明的屬性绳瘟,只會(huì)生成setter/getter方法的聲明雕憔,不會(huì)自動(dòng)生成成員變量和getter/setter方法的實(shí)現(xiàn)
- 分類不可為類添加實(shí)例變量,而擴(kuò)展可以
- 分類可以為類添加方法糖声,而擴(kuò)展只能聲明方法不能實(shí)現(xiàn)
APP優(yōu)化
APP卡頓
GCD在項(xiàng)目中的應(yīng)用
定時(shí)器問(wèn)題
APP加密加固
** APP性能優(yōu)化 **
性能優(yōu)化:
(1) 卡頓優(yōu)化
(2) 耗電優(yōu)化
(3) 啟動(dòng)優(yōu)化
卡頓優(yōu)化
屏幕成像的過(guò)程:CPU計(jì)算數(shù)據(jù) -> GPU進(jìn)行渲染 -> 屏幕發(fā)出 Vsync信號(hào) -> 成像
假如屏幕已經(jīng)發(fā)出了Vsync信號(hào)斤彼,但是GPU還沒(méi)有渲染完成,則只能將上一次的數(shù)據(jù)限時(shí)出來(lái)蘸泻,導(dǎo)致當(dāng)前計(jì)算的幀數(shù)丟失琉苇,這樣就產(chǎn)生了卡頓, 當(dāng)前計(jì)算好的數(shù)據(jù)只能等待下一個(gè)周期去渲染悦施。
解決卡頓的主要思路:盡可能減少GPU和CPU資源的消耗
按照60fps的刷幀率并扇,每隔16ms就會(huì)有一次Vsync信號(hào)
針對(duì)CPU:
1、盡量使用輕量級(jí)的對(duì)象抡诞,如:不用處理時(shí)間的UI控件可以考慮使用CALAyer
2穷蛹、不要頻繁的調(diào)用UIView的相關(guān)屬性土陪;例如:frame、bounds肴熏、transform等等
3鬼雀、盡量提前計(jì)算好布局,在有需要的時(shí)候一次性調(diào)整對(duì)應(yīng)的屬性蛙吏,不要多次修改
4源哩、AutoLayout會(huì)比直接設(shè)置frame消耗更多的CPU資源
5、圖片size和UIImageView的size保持一致
6鸦做、控制縣城的最大并發(fā)數(shù)
7励烦、耗時(shí)操作放入子線程,如:文本尺寸計(jì)算馁龟、繪制崩侠、圖片的解碼繪制等。
針對(duì)GPU
1坷檩、盡量避免短時(shí)間內(nèi)顯示大量的圖片
2却音、GPU能處理的尺寸最大紋理尺寸為4096*4096,超過(guò)這個(gè)尺寸就會(huì)占用CPU的資源
3矢炼、盡量減少透明試圖的數(shù)量和層次
4系瓢、減少透明的試圖(alpha < 1),不透明就設(shè)置opaque為YES
5句灌、盡量避免離屏渲染
光柵化:layer.shouldRastersize = YES
蒙版:layer.mask
圓角:layer.maskTobounds = YES,layer.cormerRadius>0
陰影:未設(shè)置layer.shadowPath
(2)耗電優(yōu)化
優(yōu)化I/O操作
盡可能避免頻繁寫(xiě)入小數(shù)據(jù)夷陋,最好一次性批量寫(xiě)入
讀寫(xiě)大量重要數(shù)據(jù)時(shí),可以用dispathc_io胰锌,它提供了基于GCD的異步操作文件的API骗绕,使用該API會(huì)優(yōu)化磁盤(pán)訪問(wèn)
數(shù)據(jù)量大時(shí),使用數(shù)據(jù)庫(kù)來(lái)管理數(shù)據(jù)
網(wǎng)絡(luò)優(yōu)化
多次網(wǎng)絡(luò)請(qǐng)求接過(guò)相同资昧,盡量使用緩存
使用斷點(diǎn)續(xù)傳酬土,否則網(wǎng)絡(luò)不穩(wěn)定時(shí)可能多次傳輸相同的內(nèi)容
網(wǎng)絡(luò)不可用時(shí),不進(jìn)行網(wǎng)絡(luò)請(qǐng)求
讓用戶可以取消長(zhǎng)時(shí)間或者速度很慢的網(wǎng)絡(luò)操作格带,設(shè)置合適的超時(shí)時(shí)間
批量傳輸撤缴,如下載視頻,不要傳輸很小的數(shù)據(jù)包叽唱,直接下載整個(gè)文件或者大塊下載
定位優(yōu)化
如果只是需要快速確定用戶位置屈呕,用CLLocatuibManager的requestLocation方法定位,定位硬件會(huì)自動(dòng)斷電
若不是導(dǎo)航應(yīng)用棺亭,盡量不要實(shí)時(shí)更新位置虎眨,定位結(jié)束就關(guān)閉定位服務(wù)
盡量降低定位的精度,如不適用精度最高的KCLLocationAccuracyBest
需要后臺(tái)定位時(shí),盡量設(shè)置pauseLocationUpdateAutomatically為YES专甩,若用戶不怎么移動(dòng)的時(shí)候钟鸵,系統(tǒng)會(huì)自動(dòng)暫停位置更新