1. 程式人生 > >IOS記憶體管理知識總結(一)

IOS記憶體管理知識總結(一)

    最近優化公司在優化app,總結幾個記憶體管理的知識點。

    首先我們要清楚

    1. “堆”和“棧”

Objective-C的物件在記憶體中是以堆的方式分配空間的,並且堆記憶體是由你釋放的,就是release
OC物件存放於堆裡面(堆記憶體要程式設計師手動回收)
非OC物件一般放在棧裡面(棧記憶體會被系統自動回收)
堆裡面的記憶體是動態分配的,所以也就需要程式設計師手動的去新增記憶體、回收記憶體

按管理方式分
  • 對於棧來講,是由系統編譯器自動管理,不需要程式設計師手動管理
  • 對於堆來講,釋放工作由程式設計師手動管理,不及時回收容易產生記憶體洩露
按分配方式分
  • 堆是動態分配和回收記憶體的,沒有靜態分配的堆
  • 棧有兩種分配方式:靜態分配和動態分配
    • 靜態分配是系統編譯器完成的,比如區域性變數的分配
    • 動態分配是有alloc函式進行分配的,但是棧的動態分配和堆是不同的,它的動態分配也由系統編譯器進行釋放,不需要程式設計師手動管理

    2. 單例模式

    單例模式是限制一個類只能初始化一個物件的一種設計模式,在實踐中,初始化通常在程式啟動不久後執行,而且這些物件不會銷燬,原理想必大家都很清楚,單例物件被一個全域性的靜態變數所引用,保證了他不會被釋放,每次呼叫都會先進行判斷是否已經建立,一旦建立將不會再次建立

    正是因為單例的不會被釋放,才有可能造成記憶體風險並且會增加程式的啟動時間。下面是列舉開發中的主要使用場景

  •     佇列操作(如日誌和埋點)
  •     訪問共享資源(如快取)
  •     資源池(執行緒池)

    所以在使用單例時候應該基本遵循一下原則:

  •     儘量不使用單例
  •     儘量避免物件級屬性,儘量使用本地變數

    3 依賴注入

依賴注入的本質是在需要的時候傳遞依賴,我們可以先看下下面的例子

   -   (void)someMethod{   //外部類的方法

        XXSomeClass *obj = [XXSomeClass shareInstance];  //單例物件

        NSString *someValue = [obj operation:@"some parameter"];

    }   

很明顯的發現 someMethod依賴了外部的類XXSomeClass,

  • 如果XXSomeClass在operation方法中又持有了一些資源,那麼他會一直持有,哪怕shareInstance不會被呼叫。
  • 如果XXSomeClass需要在someMethod完成某些初始化,而上游呼叫someMethod的方法並不知道而直接使用XXSomeClass,會造成XXSomeClass並未初始化

這時候就需要依賴注入了,依賴注入可以通過自定義的初始化器或者呼叫方法注入。程式碼如下:

-(instancetype)initWithSomeClass:(XXSomeClass *) someClass{

        if(self=[super init]){

            self.someClass = someClass;

        }

        return self;

    }

-(void)someMethod{

    NSString *someValue = [self.someClass operaion:@"some parameter"];

}

-(void)anotherMethodWithAnotherClass:(anotherClass*) anotherClass{

       NSString *someValue = [anotherClass operaion:@"some parameter"];

}

歡迎大家討論一個問題,方法在物件中如何儲存,呼叫過程時如果對方法以及方法中的區域性變數進行管理?