1.屬性修飾符運用需要注意的地方
在arc中券躁,基本變量之外的屬性 弱引用最好使用weak
桨螺,來避免野指針的出現(xiàn)函似,weak
可以在指向的對象dealloc的時候自動置為nil
(屬性值會清空)词爬。
在arc中使用assign
修飾delegate
是很危險的,在assign
修飾的屬性遭到摧毀時,屬性值不會清空。此時如果使用self.delegate
會造成程序crash
艺沼。
在arc中強引用盡量使用strong
胰舆,當然這里strong
和retain
的作用是一樣的骚露,但是為了保持代碼的一致性,這里推薦使用strong
缚窿。
2.在對象內(nèi)部訪問實例變量的方式
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
有兩種訪問方法:1.是通過屬性進行訪問棘幸,即setter getter方法。2.直接訪問方式滨攻。
在設置實例變量時要通過屬性訪問够话,即self. name
。因為直接訪問實例變量_name
光绕,不會調(diào)用setter方法,也就繞過了為該屬性所定義的'內(nèi)存管理語意'(即修飾符copy畜份、strong诞帐、weak……不起作用)。直接訪問也不會觸發(fā)'鍵值觀察KVO'通知爆雹。如果該屬性使用懶加載停蕉,使用直接訪問_name
也是無效的。
3.聲明常量
NSString *const kNotificationName = @"failNotificationName Name";
如果常量不是全局的钙态,請在前面加static慧起。否則可能會產(chǎn)生duplicate symbol的錯誤。
如果需要聲明全局的常量册倒,那么需要在.h 文件中加入蚓挤。
FOUNDATION_EXPORT NSString * const kNotificationName;
或者
extern NSString * const kNotificationName;
同樣我們可以使用宏來聲明變量,define預處理指令驻子。使用預處理指令有這么幾個缺點:1.定義出來的常量沒有類型信息灿意,只能做替換。2.當在其他地方修改該宏時崇呵,會導致該常量發(fā)生變化缤剧。(例如:其他的開發(fā)人員在工程中定義了同名的宏,編譯器不會報錯)而使用類型常量恰巧能解決這兩個問題域慷。
4.程序中環(huán)境的切換
在開發(fā)過程中荒辕,經(jīng)常需要切換環(huán)境。比如測試環(huán)境犹褒,開發(fā)環(huán)境抵窒,與生產(chǎn)環(huán)境。我們可以通過構建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 ];
}
因為willAppear
和Disappear
出現(xiàn)的順序并不一定是一對一的估脆。所以有可能造成多次添加,多次移除通知座云。 當視圖沒有展示的時候視圖控制器就無法接受到通知疙赠,導致一些操作沒有進行付材。
建議在 viewDidLoad
里添加通知。在dealloc
里移除通知圃阳。 當然在通知根視圖控制器 顯示操作時可以使用這種方法厌衔,避免所有已經(jīng)load的控制器 響應該通知。
6.使用懶加載
在viewDidLoad
之后捍岳,初始化的過程必然生成了對應的控件或者數(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)?shù)
特別是封裝自己的UI控件時银萍,當我們使用系統(tǒng)UI控件的代理方法時变勇,就會發(fā)現(xiàn),代理方法往往都會把控件對象作為參數(shù)傳遞過來贴唇。在這個方法中搀绣,可以訪問該對象的屬性。
- (void)textViewDidEndEditing:(YYTextView *)textView {
self.navigationItem.rightBarButtonItem = nil;
}
如果你的delegate方法戳气,只作為一個textView的委托回調(diào)链患,這種寫法沒有任何問題。但是如果你想擴展你的界面瓶您,在將來的界面中很可能出現(xiàn)另一個textView麻捻,這時你就必須區(qū)分這兩個textView是誰回調(diào)了這個代理方法。此時览闰,如果你之前并沒有添加傳入?yún)?shù)判斷芯肤,那么你還需要將之前的textView變量名字找到,并將之前的這些邏輯轉移到一個if分支內(nèi)压鉴,然后才能處理新添加的textView邏輯崖咨,這時候你的思路很可能被打斷。更糟糕的是油吭,很有可能是你的小伙伴來做這件事情击蹲。所以在擴展之前就先加上參數(shù)校驗是一個很好的習慣。
- (void)textViewDidEndEditing:(YYTextView *)textView {
if (textView == self.textView) {
self.navigationItem.rightBarButtonItem = nil;
}
}