1.屬性修飾符運(yùn)用需要注意的地方
在arc中,基本變量之外的屬性 弱引用最好使用weak,來避免野指針的出現(xiàn),weak可以在指向的對象dealloc的時(shí)候自動(dòng)置為nil(屬性值會清空)。
在arc中使用assign修飾delegate是很危險(xiǎn)的,在assign修飾的屬性遭到摧毀時(shí),屬性值不會清空。此時(shí)如果使用self.delegate會造成程序crash。
在arc中強(qiáng)引用盡量使用strong,當(dāng)然這里strong和retain的作用是一樣的,但是為了保持代碼的一致性,這里推薦使用strong。
2.在對象內(nèi)部訪問實(shí)例變量的方式
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
有兩種訪問方法:1.是通過屬性進(jìn)行訪問,即setter getter方法。2.直接訪問方式。
在設(shè)置實(shí)例變量時(shí)要通過屬性訪問,即self. name。因?yàn)橹苯釉L問實(shí)例變量_name,不會調(diào)用setter方法,也就繞過了為該屬性所定義的'內(nèi)存管理語意'(即修飾符copy、strong、weak……不起作用)。直接訪問也不會觸發(fā)'鍵值觀察KVO'通知。如果該屬性使用懶加載,使用直接訪問_name也是無效的。
3.聲明常量
NSString *const kNotificationName = @"failNotificationName Name";
如果常量不是全局的,請?jiān)谇懊婕觭tatic。否則可能會產(chǎn)生duplicate symbol的錯(cuò)誤。
如果需要聲明全局的常量,那么需要在.h 文件中加入。
FOUNDATION_EXPORT NSString * const kNotificationName;
或者
extern NSString * const kNotificationName;
同樣我們可以使用宏來聲明變量,define預(yù)處理指令。使用預(yù)處理指令有這么幾個(gè)缺點(diǎn):1.定義出來的常量沒有類型信息,只能做替換。2.當(dāng)在其他地方修改該宏時(shí),會導(dǎo)致該常量發(fā)生變化。(例如:其他的開發(fā)人員在工程中定義了同名的宏,編譯器不會報(bào)錯(cuò))而使用類型常量恰巧能解決這兩個(gè)問題。
4.程序中環(huán)境的切換
在開發(fā)過程中,經(jīng)常需要切換環(huán)境。比如測試環(huán)境,開發(fā)環(huán)境,與生產(chǎn)環(huán)境。我們可以通過構(gòu)建NSString的category返回url。
#import "NSString+URL.h"
static NSString * const kBaseURL = @"http://220.175.104.19:8080";
@implementation NSString (URL)
+ (NSString *)RequestUrlWithString:(NSString *)url
{
return [NSString stringWithFormat:@"%@%@",kBaseURL, url];
}
@end
使用方法:
NSString *url = [NSString RequestUrlWithString:@"xxx/xxxx"];
5.通知的添加和移除
看到有同事使用這種方法來添加通知與移除通知
-(void)viewWillAppear:(BOOL)animated{
[[NSNotificationCenter defaultCenter ] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil] ;
[[NSNotificationCenter defaultCenter ] addObserver:self selector:@selector(keyboardWillHidden:) name:UIKeyboardWillHideNotification object:nil] ;
}
-(void)viewWillDisappear:(BOOL)animated{
[[NSNotificationCenter defaultCenter ] removeObserver:self name:UIKeyboardWillHideNotification object:nil ] ;
[[NSNotificationCenter defaultCenter ] removeObserver:self name:UIKeyboardWillShowNotification object:nil ];
}
因?yàn)?code>willAppear和Disappear出現(xiàn)的順序并不一定是一對一的。所以有可能造成多次添加,多次移除通知。 當(dāng)視圖沒有展示的時(shí)候視圖控制器就無法接受到通知,導(dǎo)致一些操作沒有進(jìn)行。
建議在 viewDidLoad里添加通知。在dealloc里移除通知。 當(dāng)然在通知根視圖控制器 顯示操作時(shí)可以使用這種方法,避免所有已經(jīng)load的控制器 響應(yīng)該通知。
6.使用懶加載
在viewDidLoad之后,初始化的過程必然生成了對應(yīng)的控件或者數(shù)據(jù),無論這些控件或者數(shù)據(jù)是否立即有用,這會占用比較大的內(nèi)存空間。 我們可以通過重寫屬性的getter方法,來解決以上問題。
@property (nonatomic, strong) NSMutableArray *dataSource;
- (NSMutableArray *)dataSource {
if (!_dataSource) {
self.dataSource = [NSMutableArray array];
}
return _dataSource;
}
7.delegate需要校驗(yàn)傳入?yún)?shù)
特別是封裝自己的UI控件時(shí),當(dāng)我們使用系統(tǒng)UI控件的代理方法時(shí),就會發(fā)現(xiàn),代理方法往往都會把控件對象作為參數(shù)傳遞過來。在這個(gè)方法中,可以訪問該對象的屬性。
- (void)textViewDidEndEditing:(YYTextView *)textView {
self.navigationItem.rightBarButtonItem = nil;
}
如果你的delegate方法,只作為一個(gè)textView的委托回調(diào),這種寫法沒有任何問題。但是如果你想擴(kuò)展你的界面,在將來的界面中很可能出現(xiàn)另一個(gè)textView,這時(shí)你就必須區(qū)分這兩個(gè)textView是誰回調(diào)了這個(gè)代理方法。此時(shí),如果你之前并沒有添加傳入?yún)?shù)判斷,那么你還需要將之前的textView變量名字找到,并將之前的這些邏輯轉(zhuǎn)移到一個(gè)if分支內(nèi),然后才能處理新添加的textView邏輯,這時(shí)候你的思路很可能被打斷。更糟糕的是,很有可能是你的小伙伴來做這件事情。所以在擴(kuò)展之前就先加上參數(shù)校驗(yàn)是一個(gè)很好的習(xí)慣。
- (void)textViewDidEndEditing:(YYTextView *)textView {
if (textView == self.textView) {
self.navigationItem.rightBarButtonItem = nil;
}
}