iOS開發過程當中遇到的坑

1. NSTimer中的target對self進行強引用,致使代碼有保留環。html

以下代碼ios

__weak typeof(self) weakSelf = self;
scheduledTimerWithTimeInterval:0.1 target:weakSelf
                      selector:@selector(update) userInfo:nil repeats:YES];

其中,對self的引用是強引用,若是不註定調用[_timer invalidate]的話,會致使保留環。更糟糕的是,timer還會一直在後臺運行。在《Effective Object-C 2.0》第52個topic討論過這個問題。我的以爲這是NSTimer接口設計的很差,起碼應該提供一個weak版本的相似接口給開發者使用。不然,依靠外部每次stop,很容易致使內存泄露的問題。緩存


2.使用原生View進行拼接,比custom view加drawRect性能要更高。性能優化

原生的View如UIImageView,UILabel等作了性能優化,它們不經過drawRect實現自身的繪製。而是使用更高效的方式。在蘋果的文檔中,屢次提到:使用view拼湊的方式,比使用drawRect的方法效率更高。而是用drawRect的方式須要注意不要大量消耗CPU性能,不然有可能致使手機耗電和流暢性。app

我的在win32上開發時,對於custom draw使用的仍是比較頻繁的,並無任何文檔指出該方式會致使性能問題。本人以爲致使ios這個差別的關鍵點在於:iOS使用空間換時間的方式,對全部的view繪製結果進行了緩存。每一個view會對應一個layer,view的繪製首先繪製到layer上。再由compositor進行混合渲染。所以,system view會有優化的空間,若是使用drawRect基本上layer緩存的優化會大打折扣。因此,在ios開發中,會建議使用view平湊的方式獲得想要的效果。async

參考文檔: 
oop

View and Window Architecture
性能


3.對weakSelf進行強引用,獲得的是strongSelf優化

如,下面的代碼ui

__weak typeof(self) weakSelf = self;
__strong typeof(self) strongSelf = weakSelf;

雖然strongSelf引用了一個若引用的self,可是獲得的仍然是strongSelf。強弱屬性是變量自身的屬性,不會在賦值時傳遞。變量的屬性都在聲明和定義的時候就定好了。


4.當拖動scrollView時,timer計時器會中止計時,致使計時器相關的UI中止更新的問題。

把計時器用NSRunLoopCommonModes加入到主線程就能夠了。

[[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];


5.在block中使用局部self強引用strongSelf來防止weakSelf在代碼中間被釋放。

__weak __typeof__(self) weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    __strong __typeof(self) strongSelf = weakSelf;
    if (strongSelf == nil) return ;
    [strongSelf doStuff0];
    [strongSelf doStuff1];
    [strongSelf doStuff2];
});

    使用strongSelf,保證在block中self不會被釋放,若是使用的是weakSelf,在doStuff0 1 2中的某兩個方法之間時,weakSelf可能爲空(在調用doStuffx的過程當中時,weakSelf不會爲空)。若是有相似的屢次訪問strongSelf又不想每次都坐safeguard的話,能夠考慮局部強引用的方式。


6. ARC中的內存問題,release sent to deallocated object問題。

簡單來講,在某個dealloc方法中觸發了成員變量進行autorelease,可是dealloc事後,該成員變量已經被釋放了。這時autorelease再進行release就有可能觸發上述crash。若是發生相似事情能夠查一下是否是上述緣由致使的。參考:release sent to deallocated instance under ARC .. how?


7. 當使用NSTimer驅動View進行更新時,能夠在回調中判斷view是否可見進行優化。

-(void)timerDidFire {
    if (self.window == nil) {
        return ;
    }
    ...
}
相關文章
相關標籤/搜索