回答:
標準とは思えないことを始めました。
1)プロパティの出現により、「_」を使用して「プライベート」クラス変数のプレフィックスを付けることはなくなりました。結局のところ、他のクラスから変数にアクセスできる場合、そのプロパティはありませんか?私は常にコードを醜くするために "_"接頭辞を嫌っていましたが、今はそれを省くことができます。
2)プライベートなことについて言えば、私は.mファイル内のクラス拡張子のプライベートメソッド定義を次のように配置することを好みます。
#import "MyClass.h"
@interface MyClass ()
- (void) someMethod;
- (void) someOtherMethod;
@end
@implementation MyClass
部外者が気にする必要のないもので.hファイルを散らかすのはなぜですか?空の()は.mファイルのプライベートカテゴリに対して機能し、宣言されたメソッドを実装しない場合はコンパイル警告を発行します。
3)@synthesizeディレクティブのすぐ下の.mファイルの先頭にdeallocを配置することにしました。割り当て解除するものは、クラスで考えたいことのリストの一番上にあるべきではありませんか?これは、iPhoneなどの環境で特に当てはまります。
3.5)テーブルセルで、パフォーマンスのためにすべての要素(セル自体を含む)を不透明にします。つまり、すべてに適切な背景色を設定します。
3.6)NSURLConnectionを使用する場合、原則として、デリゲートメソッドを実装することをお勧めします。
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
return nil;
}
ほとんどのWeb呼び出しは非常に特異であり、特にWebサービス呼び出しの場合は、応答をキャッシュするルールよりも例外です。示されているようにメソッドを実装すると、応答のキャッシュが無効になります。
また、興味深いのは、Joseph MattielloからのiPhone固有のヒント(iPhoneメーリングリストで受け取った)です。他にもありますが、これらは私が最も一般的に有用だと思いました(いくつかのビットがオリジナルから少し編集されて、応答で提供される詳細を含めるようになっていることに注意してください)。
4)CoreLocationを使用する場合など、必要な場合にのみ倍精度を使用します。定数を 'f'で終了し、gccに定数を浮動小数点数として格納させます。
float val = someFloat * 2.2f;
これはsomeFloat
、実際にはdoubleの可能性がある場合に最も重要です。ストレージの「val」の精度が失われるため、混合モードの計算は必要ありません。iPhoneのハードウェアでは浮動小数点数がサポートされていますが、単精度ではなく倍精度演算を行うにはまだ時間がかかる場合があります。参照:
旧式の携帯電話では、計算はおそらく同じ速度で動作しますが、レジスタでは倍精度よりも単精度コンポーネントを多く使用できるため、多くの計算では単精度の方が高速になります。
5)プロパティをとして設定しますnonatomic
。それらはatomic
デフォルトであり、合成時に、マルチスレッドの問題を防ぐためにセマフォコードが作成されます。99%の人はおそらくこれを心配する必要はなく、コードを非アトミックに設定すると、肥大化が少なく、メモリ効率が高くなります。
6)SQLiteは、大きなデータセットをキャッシュする非常に高速な方法です。たとえば、マップアプリケーションはタイルをSQLiteファイルにキャッシュできます。最も高価な部分はディスクI / Oです。送信することにより、多くの小さな書き込みを避けるBEGIN;
とCOMMIT;
、大きなブロックの間。たとえば、新しい送信ごとにリセットする2秒のタイマーを使用します。有効期限が切れると、COMMITを送信します。これにより、すべての書き込みが1つの大きなチャンクに分けられます。SQLiteはトランザクションデータをディスクに保存します。これにより、Begin / Endラッピングを行うことで、多数のトランザクションファイルが作成されず、すべてのトランザクションが1つのファイルにグループ化されます。
また、SQLがメインスレッド上にある場合、GUIはブロックされます。クエリが非常に長い場合は、クエリを静的オブジェクトとして保存し、SQLを別のスレッドで実行することをお勧めします。クエリ文字列のデータベースを変更するものはすべて@synchronize() {}
ブロックでラップしてください。短いクエリの場合は、便宜を図るためにメインスレッドに残すだけです。
SQLiteの最適化に関するその他のヒントがここにありますが、ドキュメントが古くなっているように見えますが、多くの点はおそらくまだ適切です。
http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html
メソッドまたは関数がフォーマット文字列引数を取る場合、フォーマット文字列の内容を制御できることを確認する必要があります。
たとえば、文字列をログに記録するとき、文字列変数を唯一の引数としてに渡そうとするとNSLog
:
NSString *aString = // get a string from somewhere;
NSLog(aString);
この問題は、文字列にフォーマット文字列として解釈される文字が含まれている可能性があることです。これにより、誤った出力、クラッシュ、およびセキュリティの問題が発生する可能性があります。代わりに、文字列変数をフォーマット文字列に置き換える必要があります。
NSLog(@"%@", aString);
別の環境で慣れ親しんだものではなく、標準のCocoaの命名およびフォーマット規則と用語を使用します。ありますそこにココアの開発者の多くは、それらのもう一つは、あなたのコードで作業を開始したとき、それが見え、他のココアコードに似た感じならば、それははるかに親しみやすいでしょう。
何をすべきか、何をすべきでないかの例:
id m_something;
オブジェクトのインターフェイスで宣言して、メンバー変数またはフィールドと呼ばないでください。something
または_something
をその名前に使用して、インスタンス変数と呼びます。-getSomething
。ココアの正しい名前はただ-something
です。-something:
。そのはず-setSomething:
-[NSObject performSelector:withObject:]
、ではありませんNSObject::performSelector
。他に何をするにしても、Win16 / Win32スタイルのハンガリー語表記を使用しないでください。Microsoftでさえ、.NETプラットフォームへの移行でそれをあきらめました。
歴史的に、アウトレットのメモリ管理は不十分でした。現在のベストプラクティスは、アウトレットをプロパティとして宣言することです。
@interface MyClass :NSObject {
NSTextField *textField;
}
@property (nonatomic, retain) IBOutlet NSTextField *textField;
@end
プロパティを使用すると、メモリ管理のセマンティクスが明確になります。また、インスタンス変数合成を使用する場合にも、一貫したパターンを提供します。
注:Xcode 4では、これはIDEに組み込まれています。
Clang Static Analyzerを使用して、当然のことながら、Mac OS X 10.5でCおよびObjective-Cコード(まだC ++なし)を分析します。インストールして使用するのは簡単です:
(いくつかの追加の制約などがあります。特に、「デバッグ」構成でプロジェクトを分析する必要があります-詳細についてはhttp://clang.llvm.org/StaticAnalysisUsage.htmlを参照してください-しかし、それは多かれ少なかれ要約すると。)
次に、アナライザーは、コンパイラーが検出できない可能性のあるメモリー管理やその他の基本的な問題を示す一連のWebページを生成します。
これは微妙ですが便利です。自分を別のオブジェクトへのデリゲートとして渡す場合は、の前にそのオブジェクトのデリゲートをリセットしてくださいdealloc
。
- (void)dealloc
{
self.someObject.delegate = NULL;
self.someObject = NULL;
//
[super dealloc];
}
これにより、デリゲートメソッドが送信されなくなります。dealloc
エーテルに消えようとしているときに、偶然に何もメッセージを送信できないようにする必要があります。self.someObjectは、別のオブジェクト(シングルトンまたは自動解放プールなど)によって保持される可能性があり、「メッセージの送信を停止する!」と指示するまで、割り当てを解除しようとしているオブジェクトと見なされることに注意してください。公正なゲームです。
この習慣を身に付けることで、デバッグが面倒な多くの奇妙なクラッシュからあなたを救うでしょう。
同じ原則がKey Value ObservationとNSNotificationsにも適用されます。
編集:
さらに防御的に、変更:
self.someObject.delegate = NULL;
に:
if (self.someObject.delegate == self)
self.someObject.delegate = NULL;
Memory Management Programming Guide for Cocoa
: Additional cases of weak references in Cocoa include, but are not restricted to, table data sources, outline view items, notification observers, and miscellaneous targets and delegates. In most cases, the weak-referenced object is aware of the other object’s weak reference to it, as is the case for circular references, and is responsible for notifying the other object when it deallocates.
@kendell
の代わりに:
@interface MyClass (private)
- (void) someMethod
- (void) someOtherMethod
@end
使用する:
@interface MyClass ()
- (void) someMethod
- (void) someOtherMethod
@end
Objective-C 2.0の新機能。
クラス拡張については、AppleのObjective-C 2.0リファレンスで説明されています。
「クラス拡張により、プライマリクラス@interfaceブロック内以外の場所にあるクラスに必要な追加のAPIを宣言できます」
したがって、それらは実際のクラスの一部であり、クラスに加えて(プライベート)カテゴリではありません。微妙だが重要な違い。
()
代わりに(Private)
(または他のカテゴリ名)を使用することにはかなり重要な利点があります。プロパティは読み取り専用として再公開できますが、一般には読み取り専用です。:)
通常、(1)それらの存続期間を直接制御することはできないため、自動解放されたオブジェクトは比較的長期間持続し、アプリケーションのメモリフットプリントを不必要に増やす可能性があります。デスクトップではこれはほとんど影響がないかもしれませんが、より制約のあるプラットフォームでは、これは重大な問題になる可能性があります。したがって、すべてのプラットフォーム、特に制約の多いプラットフォームでは、自動解放オブジェクトにつながるメソッドの使用を避けることがベストプラクティスと見なされ、代わりにalloc / initパターンを使用することをお勧めします。
したがって、以下ではありません。
aVariable = [AClass convenienceMethod];
可能な場合は、代わりに次を使用する必要があります。
aVariable = [[AClass alloc] init];
// do things with aVariable
[aVariable release];
新しく作成されたオブジェクトを返す独自のメソッドを作成するときは、Cocoaの命名規則を利用して、メソッド名の先頭に「new」を付けることで、解放する必要があることをレシーバーに通知できます。
したがって、代わりに:
- (MyClass *)convenienceMethod {
MyClass *instance = [[[self alloc] init] autorelease];
// configure instance
return instance;
}
あなたは書くことができます:
- (MyClass *)newInstance {
MyClass *instance = [[self alloc] init];
// configure instance
return instance;
}
メソッド名は「new」で始まるため、APIのコンシューマーは、受け取ったオブジェクトを解放する責任があることを知っています(たとえば、NSObjectControllerのnewObject
methodを参照)。
(1)独自のローカル自動解放プールを使用して制御できます。詳細については、「自動解放プール」を参照してください。
NSAutoreleasePool
。しかし、これが本当に問題であることを確認した後でのみ。時期尚早の最適化など…
これらのいくつかはすでに言及されていますが、ここで私が頭のてっぺんから考えることができるものは次のとおりです。
#pragma mark [section]
ます。通常、私は自分のメソッド、各サブクラスのオーバーライド、および情報または正式なプロトコルごとにグループ化します。これにより、まさに私が探しているものにジャンプするのがずっと簡単になります。同じトピックで、類似のメソッド(テーブルビューのデリゲートメソッドなど)をグループ化し、どこかに貼り付けないでください。#define
が行うときにivarを作成する、データが必要になるたびに配列をソートする代わりに配列をキャッシュするなど、多くのことを実際にカバーしています。これについて私が言えることはたくさんありますが、最終的には、必要になるか、プロファイラーから指示されるまで、コードを記述しないでください。長期的に見ると、メンテナンスがずっと簡単になります。NSLog( @"stub" )
内部に置くことでそれを示すか、または追跡しておきます。Finish what you start
する// TODO:
ためにも使用できます。
単体テストを記述します。Cocoaでは、他のフレームワークでは難しいかもしれない多くのことをテストできます。たとえば、UIコードを使用すると、通常、接続されていることを確認し、使用時に機能することを信頼できます。また、状態を設定し、デリゲートメソッドを簡単に呼び出してテストできます。
また、内部メソッドのテストを作成するときに邪魔になる、パブリックメソッドとプロテクトメソッドとプライベートメソッドの可視性もありません。
Java / C#/ C ++ / etcのようにObjective-Cを記述しないでください。
Java EE Webアプリケーションの作成に慣れているチームがCocoaデスクトップアプリケーションを作成しようとしているのを見たことがあります。Java EE Webアプリケーションであるかのように。FooクラスとおそらくFooableプロトコルだけが必要なときに、たくさんのAbstractFooFactoryとFooFactory、IFooとFooが飛び交っていました。
これを行わないようにすることの一部は、言語の違いを本当に理解することです。たとえば、Objective-Cクラスのメソッドはインスタンスメソッドと同じように動的にディスパッチされ、サブクラスでオーバーライドできるため、上記の抽象ファクトリおよびファクトリクラスは必要ありません。
必ずDebugging Magicページをブックマークしてください。これは、Cocoaバグの原因を見つけようとしているときに、壁に頭をぶつけたときの最初のストップです。
たとえば、後でアプリを終了するときなどに、後でクラッシュを引き起こしているメモリを最初に割り当てたメソッドを見つける方法がわかります。
私がNewbiecategoryaholismと呼ぶことにしたものを避けてください。Objective-Cの初心者がカテゴリを発見すると、それらはしばしば乱暴になり、存在するすべてのクラスに便利な小さなカテゴリを追加します(「何ですか?数値をローマ数字に変換してNSNumberに変換するメソッドを追加できます!」)。
これを行わないでください。
コードはより移植性が高く、理解しやすくなります。ダースクラスを20ダース上に分散させた、数十の小さなカテゴリメソッドが必要になります。
ほとんどの場合、コードを合理化するためにカテゴリメソッドが本当に必要だと思うときは、メソッドを再利用することはありません。
カテゴリメソッドを名前空間に使用している場合を除いて、他にも危険があります(完全に異常なddribin以外は誰ですか?)アドレススペースで実行されているApple、プラグイン、またはその他のものも同じカテゴリを定義する可能性があります。同じ名前のメソッドで、副作用が少し異なります...
OK。警告されたので、「この部分を実行しない」を無視してください。しかし、極端な拘束を行使してください。
世界のサブクラス化に抵抗する。Cocoaでは、他のフレームワークではサブクラス化を介して行われる、基本的なランタイムの委任と使用によって多くのことが行われます。
たとえば、Javaでは匿名*Listener
サブクラスのインスタンスを多く使用し、.NETではEventArgs
サブクラスを多く使用します。Cocoaではどちらもしません—代わりにtarget-actionが使用されます。
文字列を並べ替えてユーザーに提示するときは、単純なcompare:
方法を使用しないでください。代わりに、localizedCompare:
またはなどのローカライズされた比較メソッドを常に使用する必要がありますlocalizedCaseInsensitiveCompare:
。
詳細については、「文字列の検索、比較、および並べ替え」を参照してください。
通常、すべてのプロパティに対してObjective-C 2.0で宣言されたプロパティ機能を使用する必要があります。それらがパブリックでない場合は、クラス拡張に追加します。宣言されたプロパティを使用すると、メモリ管理のセマンティクスがすぐに明確になり、deallocメソッドを確認しやすくなります。プロパティ宣言をグループ化すると、それらをすばやくスキャンして、deallocメソッドの実装と比較できます。
プロパティを「非アトミック」としてマークしない場合は、よく考える必要があります。言語ガイドのプログラミングのObjective Cのノートを、プロパティは、デフォルトでは、原子であり、負担はかなりのオーバーヘッド。さらに、すべてのプロパティをアトミックにするだけでは、アプリケーションがスレッドセーフになるわけではありません。もちろん、 'nonatomic'を指定せずに独自のアクセサメソッドを実装する場合(それらを合成するのではなく)、アトミックな方法で実装する必要があることにも注意してください。
NSAssertとその仲間を使用します。私は常にnilを有効なオブジェクトとして使用しています...特にnilへのメッセージの送信はObj-Cでは完全に有効です。ただし、変数の状態を本当に確認したい場合は、NSAssertとNSParameterAssertを使用します。これにより、問題を簡単に追跡できます。
シンプルだが忘れられがちなもの。仕様によると:
一般に、同じセレクター(同じ名前)を持つ異なるクラスのメソッドも、同じ戻り値と引数の型を共有する必要があります。この制約は、動的バインディングを可能にするためにコンパイラーによって課されます。
その場合、同じ名前のセレクターはすべて、たとえ異なるクラスであっても、戻り値/引数の型が同じであると見なされます。これは簡単な例です。
@interface FooInt:NSObject{}
-(int) print;
@end
@implementation FooInt
-(int) print{
return 5;
}
@end
@interface FooFloat:NSObject{}
-(float) print;
@end
@implementation FooFloat
-(float) print{
return 3.3;
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id f1=[[FooFloat alloc]init];
//prints 0, runtime considers [f1 print] to return int, as f1's type is "id" and FooInt precedes FooBar
NSLog(@"%f",[f1 print]);
FooFloat* f2=[[FooFloat alloc]init];
//prints 3.3 expectedly as the static type is FooFloat
NSLog(@"%f",[f2 print]);
[f1 release];
[f2 release]
[pool drain];
return 0;
}
Leopard(Mac OS X 10.5)以降を使用している場合は、Instrumentsアプリケーションを使用してメモリリークを検出および追跡できます。Xcodeでプログラムをビルドした後、[実行]> [パフォーマンスツールで開始]> [リーク]を選択します。
アプリでリークが表示されない場合でも、オブジェクトを長時間保持している可能性があります。Instrumentsでは、これにObjectAllocインストゥルメントを使用できます。InstrumentsドキュメントでObjectAllocインストゥルメントを選択し、[表示]> [詳細]を選択して、インストルメントの詳細を表示します(まだ表示されていない場合)(横にチェックマークが付いているはずです)。ObjectAllocの詳細の[Allocation Lifespan]で、[Created&Still Living]の横にあるラジオボタンを必ず選択してください。
アプリケーションの記録を停止するときはいつでも、ObjectAllocツールを選択すると、「#Net」列に、アプリケーション内の各静止オブジェクトへの参照の数が表示されます。自分のクラスだけでなく、NIBファイルの最上位オブジェクトのクラスも確認してください。たとえば、画面にウィンドウがなく、まだ生きているNSWindowへの参照が表示されている場合、それをコードで解放していない可能性があります。
deallocでクリーンアップします。
これは忘れることが最も簡単なことの1つです-esp。150mphでコーディングするとき。常に、常に、常にdeallocで属性/メンバー変数をクリーンアップします。
-私はにObjC 2の属性を使用したいと、これはクリーンアップ無痛になりますので、 -新しいドット表記を。多くの場合、次のように単純です。
- (void)dealloc
{
self.someAttribute = NULL;
[super dealloc];
}
これでリリースが処理され、属性がNULLに設定されます(防御プログラミングを検討します-deallocでさらに別のメソッドが再度メンバー変数にアクセスする場合-まれですが、発生する可能性があります)。
10.5でGCをオンにすると、これはそれほど必要なくなります。ただし、作成した他のリソースをクリーンアップする必要がある場合は、代わりにfinalizeメソッドで実行できます。
これらのコメントはすべてすばらしいですが、しばらく前に公開されたGoogleのObjective-Cスタイルガイドについて誰も触れなかったことに本当に驚いています。彼らは非常に徹底した仕事をしたと思います。
また、準関連トピック(より多くの回答の余地あり!):
初心者が使用するかなり明白な1つ:コードにXcodeの自動インデント機能を利用します。別のソースからコピー/貼り付けしている場合でも、コードを貼り付けたら、コードのブロック全体を選択して右クリックし、そのブロック内のすべてをインデントし直すオプションを選択できます。
Xcodeは実際にそのセクションを解析し、ブラケット、ループなどに基づいてインデントします。各行ごとにスペースバーまたはタブキーを押すよりもはるかに効率的です。
最初にCocoaプログラミングを始めたとき、これを見落としていたことを知っています。
NIBファイルに関するメモリ管理の責任を理解していることを確認してください。ロードするNIBファイル内の最上位オブジェクトを解放する必要があります。この件に関するAppleのドキュメントを読んでください。
すべてのGCC警告をオンにしてから、Appleのヘッダーによって定期的に発生する警告をオフにして、ノイズを減らします。
また、Clang静的分析を頻繁に実行します。「スタティックアナライザーの実行」ビルド設定を使用して、すべてのビルドで有効にすることができます。
単体テストを作成し、ビルドごとに実行します。
変数とプロパティ
1 /ヘッダーをクリーンに保ち、実装を
非表示にするヘッダーにインスタンス変数を含めないでください。プロパティとしてクラス継続に配置されるプライベート変数。パブリック変数は、ヘッダーでパブリックプロパティとして宣言します。読み取り専用にする必要がある場合は、読み取り専用として宣言し、クラスの継続でreadwriteとして上書きします。基本的に私は変数をまったく使用せず、プロパティのみを使用しています。
2 /プロパティにデフォルト以外の変数名を付けます。例:
@synthesize property = property_;
理由1:「自己」を忘れることによって引き起こされるエラーをキャッチします。プロパティを割り当てるとき。理由2:私の実験から、InstrumentsのLeak Analyzerは、デフォルト名でリークするプロパティを検出するのに問題があります。
3 /プロパティで直接保持または解放を使用しないでください(または非常に例外的な状況でのみ)。deallocでそれらにnilを割り当てるだけです。保持プロパティは、保持/解放を単独で処理するためのものです。たとえば、セッターがオブザーバーを追加または削除していないかどうかはわかりません。変数は、セッターとゲッターの内部でのみ直接使用する必要があります。
ビュー
1 /可能であれば、すべてのビュー定義をxibに配置します(例外は通常、動的コンテンツとレイヤー設定です)。時間を節約し(コードを書くより簡単です)、変更が簡単で、コードをクリーンに保ちます。
2 /ビューの数を減らしてビューを最適化しようとしないでください。コードにサブビューを追加したいという理由だけで、xibの代わりにUIImageViewを作成しないでください。代わりに、UIImageViewを背景として使用してください。ビューフレームワークは何百ものビューを問題なく処理できます。
3 / IBOutletsは、常に保持(または強力)する必要はありません。ほとんどのIBOutletはビュー階層の一部であるため、暗黙的に保持されることに注意してください。
4 / viewDidUnloadのすべてのIBOutletを解放する
5 / deallocメソッドからviewDidUnloadを呼び出します。暗黙的に呼び出されることはありません。
記憶
1 /作成時にオブジェクトを自動解放します。多くのバグは、リリースコールを1つのif-elseブランチに移動するか、returnステートメントの後で発生します。自動リリースではなくリリースは、例外的な状況でのみ使用する必要があります。たとえば、実行ループを待機していて、オブジェクトの自動リリースが早すぎたくない場合などです。
2 / Authomatic Reference Countingを使用している場合でも、retain-releaseメソッドの仕組みを完全に理解する必要があります。手動で保持リリースを使用することは、ARCほど複雑ではありません。どちらの場合も、リークと保持サイクルについて考慮する必要があります。大きなプロジェクトや複雑なオブジェクト階層では、retain-releaseを手動で使用することを検討してください。
コメント
1 /コードを自動ドキュメント化します。すべての変数名とメソッド名は、それが何をしているかを伝える必要があります。コードが正しく記述されている場合(これには多くの練習が必要です)、コードのコメントは必要ありません(ドキュメントのコメントと同じではありません)。アルゴリズムは複雑になる可能性がありますが、コードは常に単純でなければなりません。
2 /時には、コメントが必要になることがあります。通常は、明らかでないコードの動作やハックを説明します。コメントを書く必要があると思われる場合は、最初にコードを書き直して、コメントを必要としないようにしてください。
インデント
1 /インデントを大きくしすぎないでください。ほとんどのメソッドコードは、メソッドレベルでインデントする必要があります。ネストされたブロック(もしあれば)は、読みやすさを低下させます。ネストされたブロックが3つある場合は、内部ブロックを別のメソッドに配置する必要があります。4つ以上のネストされたブロックは使用しないでください。メソッドコードの大部分がif内にある場合は、if条件を否定します。次に例を示します。
if (self) {
//... long initialization code ...
}
return self;
if (!self) {
return nil;
}
//... long initialization code ...
return self;
Cコード、主にC構造体を理解する
Obj-Cは、C言語上の軽いOOPレイヤーにすぎないことに注意してください。Cの基本的なコード構造(列挙型、構造体、配列、ポインタなど)がどのように機能するかを理解する必要があります。例:
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height + 20);
と同じです:
CGRect frame = view.frame;
frame.size.height += 20;
view.frame = frame;
などなど
独自のコーディング標準ドキュメントを作成し、頻繁に更新します。バグから学ぶようにしてください。バグが作成された理由を理解し、コーディング標準を使用してバグを回避してください。
現在、コーディング標準には約20ページがあり、Javaコーディング標準、Google Obj-C / C ++標準、および独自の追加が混在しています。コードを文書化し、標準の標準インデント、空白、空白行を適切な場所に使用します。
より機能的になります。
Objective-Cはオブジェクト指向言語ですが、Cocoaフレームワークは機能的なスタイルを認識しており、多くの場合、機能的なスタイルで設計されています。
可変性の分離があります。不変クラスをプライマリとして、可変オブジェクトをセカンダリとして使用します。たとえば、主にNSArrayを使用し、必要な場合にのみNSMutableArrayを使用します。
純粋な機能があります。それほど多くはありませんが、純粋な関数のように設計されたフレームワークAPIの多くを購入してください。CGRectMake()
またはなどの関数を見てくださいCGAffineTransformMake()
。明らかに、ポインタ形式はより効率的に見えます。ただし、ポインタを使用した間接的な引数は、副作用のないものにはなりません。構造をできるだけ純粋に設計します。状態オブジェクトを分離します。他のオブジェクトに値を渡すときの-copy
代わりに使用し-retain
ます。共有された状態は、他のオブジェクトの値への変更に静かに影響を与える可能性があるためです。だから、副作用のないことはできません。オブジェクトの外部からの値がある場合は、それをコピーします。したがって、共有状態を最小限に抑えることも重要です。
ただし、不純な関数の使用も恐れないでください。
怠惰な評価があります。-[UIViewController view]
プロパティのようなものを参照してください。オブジェクトが作成されても、ビューは作成されません。発信者がview
最初にプロパティを読んだときに作成されます。UIImage
実際に描画されるまで読み込まれません。この設計のような多くの実装があります。この種の設計はリソース管理に非常に役立ちますが、遅延評価の概念を知らなければ、それらの動作を理解するのは簡単ではありません。
閉鎖があります。Cブロックをできるだけ使用します。これはあなたの人生を大幅に簡素化します。ただし、使用する前に、ブロックメモリ管理についてもう一度お読みください。
セミオートGCがあります。NSAutoreleasePool。-autorelease
プライマリを使用します。-retain/-release
本当に必要な場合は、手動セカンダリを使用してください。(例:メモリの最適化、明示的なリソースの削除)
autorelease
はメモリを一般的に長く保持することに同意し、マニュアルretain/release
はケースのメモリ消費を減らすことができます。しかしそれは、特殊なケースの最適化のための指針(も、あなたがいつも感じている!)あるべきな時期尚早な最適化を一般化する理由にはできません練習。そして実際、あなたの提案は私と反対ではありません。私はそれが本当に必要な場合として言及しました:)