Objective-Cの学習-5日目

6489 ワード

チュートリアルの詳細:
技術:Objective-C難易度:初心者完成時間:20-30分
Objective-Cシリーズのチュートリアルの第5部へようこそ.今日はメモリ管理を見てみましょう.初心者のために用意されたObjective-Cの章ですよ.ほとんどのスクリプト言語(PHPなど)はメモリ自動管理を採用していますが、Objective-Cはメモリを慎重に使用し、オブジェクトを手動で作成して解放する必要があります.
これは良い方法で、どれだけのメモリがアプリケーションで使用されるかを制御します.そうすれば、システムのメモリの漏洩に遭遇することはありません.さらに重要なのは、モバイルシステム、例えばiPhoneのメモリがデスクトップマシンよりも限られていることです.
二つの方法
Objective-Cには2つのメモリ管理方式があり、1つ目は参照カウント、2つ目はゴミ回収である.カウントリファレンスはプログラムコードで実現され、ゴミ回収はシステムがメモリを自動的に管理するため、手動と自動の2種類と考えることができます.注意しなければならないのは、iPhoneにゴミ回収機能がないことです.それが、私たちがその仕事を深く研究していない理由です.プログラムがMacを実行している場合は、アップルのドキュメントでゴミ回収の仕組みを解放することができます.
参照数
ええと、メモリをどのように管理すればいいですか?まず、いつ私たちのコードでメモリを使用しますか?クラスのインスタンスを作成すると、メモリが申請され、使用できます.今では、小さなオブジェクトでは大きな注目を集めることはできませんが、アプリケーションの規模が大きくなると、すぐに注意を喚起します.
まず、1つの例を見てみましょう.各グラフィックの形状は個別のオブジェクトです.ユーザが100個の形状を描くと,メモリに100個のオブジェクトが存在する.これで、ユーザーが画面を再開してクリアした後、別の100のオブジェクトを描きます.メモリを管理していない場合は、200のオブジェクトがメモリを占めて何もしません.
参照カウントで計算します.新しいオブジェクトを作成してメモリを申請すると、オブジェクトは1つのカウントを保持します.このオブジェクトを保持するように要求すると、カウンタは2になります.このオブジェクトを解放すると、カウンタは1に戻ります.ただし、カウンタが0になると、システムはこのオブジェクトを回収し、メモリを解放します.
構文
メモリに影響を与える方法はいくつかあります.まず、alloc、新規作成、レプリケーションなどの名前でオブジェクトを作成する場合、オブジェクトを使用してメソッドを保存すると、これも真実です.手動でオブジェクトを解放したり、自動的に解放したりすると、オブジェクトの所有権がどのように変化したかに関心を持つ必要はありません.
したがって、オブジェクトのメモリを申請すると、次のようになります.
   1:  myCarClass *car = [myCarClass alloc];  

車のオブジェクトに責任を負い、手動で解放(または自動解放)しなければなりません.この点が重要です.自動解放に設定されたオブジェクトを手動で解放しようとすると、アプリケーションがクラッシュする可能性がありますよ.
allocでオブジェクトを作成した以上、carオブジェクトはカウント1を保存し、解放されないことを意味します.私たちが保存したオブジェクトであれば、次のようにします.
   1:  [car retain];  

メモリカウントは2です.しかし、オブジェクトを解放するには、カウントを0に設定するために2回解放する必要があります.現在のカウントが0なので、このオブジェクトはクリーンアップされます.
自動リリースおよび自動リリースプール(Autorelease and Autorelease Pool’s)
Xcodeプロジェクトを新規作成すると、デフォルトで生成された自動リリースプールに関するコードにも気づくかもしれません.今は無視されているかもしれませんが、何をしているのか、どこで使用しているのかを見てみましょう.
あなたのコードはこれらに似ているかもしれません.
   1:  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];   
   2:  [pool drain]; 

注意:古いドキュメントを指す場合は、言語の新しい特性ですが、基本的には同じことをします.
ここで、上記のコードが何をしているのか分かるでしょう.poolというNSAutoReleasePoolインスタンスを作成し、メモリを割り当て、initメソッドで初期化します.
Autoreleaseメッセージをオブジェクトに送信すると、そのオブジェクトは内部の最も深い自動解放プールに追加されます(プールは互いにネストできるため、後で詳しく説明します).プールが破棄メッセージを受信すると、自動的に解放されたオブジェクトはすべて解放され、遅延に基づいて自動的に解放されます.
これは、多くの方法でオブジェクトが返されるため、通常は自動放出オブジェクトが返されます.これは、オブジェクトのカウントに関心を持つ必要がなく、使用するだけで、解放の問題を管理する必要がありません.それは自分で完成したからです.
ネストされた自動リリースプール
以前、ネストされた自動リリースプールについて言及しましたが、私たちはこれを使って何をしていますか?いくつかの使い方がありますが、最も一般的な使い方は、一時オブジェクトを使用するループでネストされた自動リリースプールを使用することです.
たとえば、2つの一時オブジェクトを作成するためのループがあります.この2つのオブジェクトを自動的に解放するように設定すると、破棄メッセージをループ送信するまで使用できます.手動でメモリ割り当てを解放する必要はありません.アップル社には、ドキュメントにネストされた自動リリースプールを使用すると、次のような例があります.
   1:  void main()   
   2:  {   
   3:      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];   
   4:    
   5:      NSArray *args = [[NSProcessInfo processInfo] arguments];   
   6:    
   7:      for (NSString *fileName in args) {   
   8:    
   9:          NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];   
  10:    
  11:          NSError *error = nil;   
  12:          NSString *fileContents = [[[NSString alloc] initWithContentsOfFile:fileName   
  13:                               encoding:NSUTF8StringEncoding error:&error] autorelease];   
  14:    
  15:          /* Process the string, creating and autoreleasing more objects. */  
  16:    
  17:          [loopPool drain];   
  18:      }   
  19:    
  20:      /* Do whatever cleanup is needed. */  
  21:      [pool drain];   
  22:    
  23:      exit (EXIT_SUCCESS);   
  24:  } 

上の例は少し余計ですが、この構造は必要です.ご覧のように、アプリケーションが開きmain関数がロードされるとpoolという自動解放プールが作成されます.つまり、poolが破棄メッセージを送信する前に、自動解放されたすべてのオブジェクトが自動解放プールに割り当てられます.自動解放プールがすでに存在しない限り(申し訳ありませんが、これは理解できません).
ループでは、loopPoolという別の自動リリースプールが作成されます.このプールはループで破棄されるので、ループで自動的に解放されるすべてのオブジェクトはループが終了する前に解放されます.
内層の自動放出プールは外層の自動放出プールに影響しません.必要に応じて多くの自動放出プールを内蔵するかもしれません.ループで解放自動を使用すると、単独の自動解放プールがない場合、main関数が終わるまで作成したすべてのオブジェクトは解放されません.したがって、100回サイクルすると、100個のオブジェクトがメモリを消費し、アプリケーションが膨張します.
保存数
終了する前に、メモリの管理が容易になる知識を見てみましょう.現在、オブジェクトを作成すると、オブジェクトの参照数などを覚えていますが、実際の数字は見えません.より良い学習のために、ここではretainCountというオブジェクトの参照数を見極める方法があり、オブジェクトの参照数を出力します.
   1:  NSLog(@"retainCount for car: %d", [car retainCount]);  

retainCountメソッドは整数を返しますので、%dでコンソールにマークします.ごく少数のインスタンスのretainCountでエラーが発生するため、プログラミングに100%依存すべきではなく、デバッグに依存すべきであるため、アプリケーションがretainCoutメソッドを使用しないように実行されています.
まとめ:
初心者たちは、内面管理が難しいテーマだと感じがちです.特に他の言語から移行した子供靴たちです.アプリケーションの作成時に使用するのに十分な基本的な知識を紹介しました.
アップルは開発者のウェブサイトに超大きな開発ドキュメントライブラリを持っています.今日接触した知識がぼやけているときは、もっと読むことをお勧めします.チュートリアルの簡素化に力を入れ、メモリ管理をよりよく理解できるようにしているので、拡張はあまりありません.
いつものように、質問を歓迎します.
に挑戦
コンソールにいくつかの変数を含む単純なインスタンスを作成し、そのようなインスタンスを作成し、retainCountメソッドで参照カウントを表示する簡単な実践です.メモリ管理を理解する最善の方法は、Xcodeを開き、allocやretainなどの知識を使用することです.エラーやプログラムのクラッシュを恐れないでください.これは今後のプログラミングに経験を積みます.
次のセクション
次のレッスンでは、カテゴリ、Objective-Cの大きな特性を学び、多くの時間を節約し、符号化を簡単にします.
チュートリアルのナビゲーション
<<学習Objective-C--4日目学習Objective-C--6日目>>