[OC] オブジェクト指向基盤と基盤フレームワークの概要


序文

著者は 3 週間かけて OC の基礎知識を学び、学んだ知識を要約して応用するためにこのブログを書きます。

1. オブジェクト指向

1. クラスとオブジェクト

クラスとオブジェクトは、オブジェクト指向プログラミング言語の非常に重要な部分です。クラスを通じてオブジェクトを作成します。クラスを作成する手順は、インターフェイス部分と実装部分の 2 つの部分に分かれています。インターフェイスはメソッドとメンバー変数を定義するために使用され、@property を使用してプロパティを定義することもできます。実装部分はメソッドの実装を提供します。

2. オブジェクトの作成と使用

次に、オブジェクトの作成と使用を開始します。次に、オブジェクトの例を作成しましょう。 FKUser *a = [[FKUser alloc] init];

ここで、 a は変数名、FKUser はクラス、alloc は作成したオブジェクトにヒープ メモリ内のスペースを割り当てます。
ここでは、 alloc を理解することに重点を置く必要があります。 alloc を使用するときは、実際に allocWithZone を呼び出します。これは、後でシングルトン モードを使用するときに使用されます。
次に、メソッドを呼び出す方法があります。メソッドの呼び出し方法は、主語-動詞-目的語という日常の会話のロジックに従います。
主語はクラスまたはオブジェクト、述語はメソッド、オブジェクトは渡すパラメータです。
たとえば、Cai Xukun はバスケットボールをします: Cai Xukun はオブジェクト、遊びはメソッド、そしてバスケットボールはパラメータです。場合によっては、メソッドがパラメータを渡す必要がない場合があるため、現時点ではオブジェクトがありません。

3. シングルトンモード

次に、より重要なシングルトン モードです。実際、私たちのシングルトン モードはシングルトン クラス モードとも呼ばれます。これはクラス メソッドです。特定の関数については後ほど研究を続け、ブログの概要を書きます。ここで最初に質問します: なぜ 2 つのメソッドによって作成されるシングルトン変数のアドレスが異なるのですか? その後、学習の過程で、著者は徐々にこの問題を解決し、シングルトン モードを改善します: 実装部分: 関数部分: ここ出力
0

ここに画像の説明を挿入

ここに画像の説明を挿入

4. 隠蔽とカプセル化

次に、隠蔽とカプセル化のセクションです。ここでさらに重要なのは、いくつかのアクセス制御文字と@property であり、ここで強調する必要があります。プロパティはメンバー変数です次に、覚えておく必要があるのは、プロテクト アクセス制御により、このクラスとそのサブクラスでメンバー変数にアクセスできるようになることです。インターフェイス部分でメンバー変数を定義すると、デフォルトでプロテクトが使用されます。
次に、ドット構文を使用するときのもう 1 つのポイントは、ドット構文はclass のプロパティにアクセスすることであり、本質は set メソッドと get メソッドを呼び出すことです。-> デフォルトではメンバー変数にアクセスしますが、メンバー変数は保護されていることが多いため、エラーがよく発生します。

5. オブジェクトの初期化

次に、オブジェクトの初期化に進みます。本来、init メソッドはオブジェクトのメンバー変数を初期値として設定するものですが、コードの再利用を減らすために init メソッドを書き直すこともできます。
オブジェクト初期化のテンプレートは次のとおりです。
ここに画像の説明を挿入
ここで著者はself = [super init]
について説明しています。 その前に、self キーワードについて説明する必要があります。self キーワードは常に、メソッドが呼び出されるオブジェクトを指します。self キーワードの最大の機能は、クラス内のメソッドがクラスの別のメソッドおよびメンバー変数にアクセスできるようにすることです。このことから、self キーワードは一般的に実装部分で使用されることがわかります。もう 1 つのポイントは、self キーワードはインスタンス メソッドのみを呼び出すことができるということです
このコードは、オブジェクトが正常に作成された場合、このオブジェクトに初期値を割り当てることを意味します。

6. 継承

次に継承部分です。
継承部分の特徴は、サブクラスが親クラスによって公開されたメンバー変数とメソッドを継承し、サブクラスが親クラスのメソッドをオーバーライドできることです。
スーパー キーワードは、サブクラスのメソッドが書き換え後に親クラスのメソッドを呼び出せるようにすることです。

7. ポリモーフィズム

クラス多態性の鍵は、プログラムがコンパイル フェーズと実行フェーズに分割されていることです。変数の型はコンパイル フェーズの型であり、オブジェクトに割り当てられた領域のクラスは実行フェーズの型です。クラスのメソッドはコンパイル フェーズでのみ呼び出すことができますが、最後の呼び出しは実行フェーズのクラスのメソッドである必要があります。また、ランタイム クラスには存在するがコンパイル時には存在しないメソッドを呼び出すことはできないことも覚えておく必要があります。

さあ、オブジェクト指向の次の部分に進みます。

8. クラスと処理オブジェクトのパッケージ化

まず、クラスのパッケージ化とオブジェクトの処理について学びます oc がオブジェクト指向プログラミング言語であることは知っていますが、C 言語を拡張したものでもあります。しかし、C 言語の基本的な型は、int や double などのオブジェクトではありません。これらにはオブジェクト特性がなく、呼び出す属性メソッドもありません。NSNumber
と NSValue はラッパー クラスであり、基本的なタイプのデータを NSArray コレクションに追加できます。oc ではコレクション内の要素がオブジェクトである必要があるため、
基本型をオブジェクトにラップするときの一般的な方法は、クラス メソッドを使用して型固有の値を NSNumbers に直接ラップすることです。
これらのメソッドの鍵となるのは、クラス メソッドを呼び出してプリミティブ型をオブジェクトにラップし、コレクションに追加します。

9. 記述方法を書き換える

値をオブジェクトにラップした後、必ずそれを出力する必要があります。NSLog を使用してオブジェクトのみを出力する場合、実際には description メソッドを呼び出して class の 16 進数を返しますが、これを取得するのではなく、必要なのはその値なので、 description メソッドを書き直す必要があります。

10. == と isEqual

= = と isEqual メソッドも、私たちの oc 研究の焦点です。
== は、2 つの変数のアドレスが同じ場合にのみ true を返します。isEqual は、すべてのポインター変数が他のポインター変数と等しいかどうかを判断するために呼び出すことができるインスタンス メソッドです。
ただし、NSObject の isEqual は実際には == と何ら変わりませんが、このメソッドは NSString クラスで書き直されており、その標準は 2 つの文字列の文字シーケンスが同じである限り true を返すことに注意する必要があります。
もう 1 つのポイントは、メモリを節約するために、2 つの同一のインスタンス変数を作成するときに、oc がこれら 2 つのポインター変数を同じオブジェクトに指すようにすることです。

11. カテゴリと拡張子

次の学習行はカテゴリと拡張です。
カテゴリを使用すると、親クラスのソース コードにアクセスしたり、サブクラスを作成したりすることなく、既存のクラスに新しいメソッドを動的に追加できます。通常、カテゴリの h ファイルでモジュラー メソッドを定義し、それを m ファイルに実装します。
ただし、拡張機能はメソッドを定義するためにのみ使用され、メソッドの実装部分はクラスに実装されます。

12. 契約と委託

次に、より重要な契約と手数料について説明します。
カテゴリを使用して契約をシミュレーションできます。ここでは、正式な契約に焦点を当てます。
私たちのプロトコルは、クラスと同様に相互に継承でき、プロトコル内で継承できます。メソッドのみを定義できますメソッド実装を提供せずに。
ただし、ここでプロトコルの継承形式に注意する必要があり、
ここに画像の説明を挿入
クラスのインターフェイス部分にクラスを継承する必要があるクラスを追加する必要があり、通常はNSObject を選択し、実装する必要があるプロトコルに従います。
また、メソッドを実装する必要があるか、実装することを選択するかを判断するために 2 つのキーワードも使用します。
@required は実装する必要があります
@optional は実装することを選択します

2、基礎フレームワーク

ここでは主に、NSString、NSDate、コレクション クラスなど、フレームワークに含まれるいくつかのクラスについて説明します。

1. NSStringクラス

NSString オブジェクトに値を割り当てる方法は、文字列定数をオブジェクトに直接割り当てることです。たとえば、NSString *str = @"hello";
NSString は不変であるため、元の文字列の後に文字列を追加または初期化するいくつかのメソッドを介してオブジェクトを間接的に変更することしかできません。たとえば、これら 2 つのメソッドは次のとおりです
ここに画像の説明を挿入
オブジェクトは変更されず、新しく生成された文字列が str ポインタ変数に再割り当てされます。

2. NSMutableString クラス

私たちのクラスは上記のクラスとは異なります。その文字シーケンスは変更できます。いくつかのメソッドを通じて使用します。ここで、可変と不変の違いに注意することができます: NSString オブジェクトを割り当てるとき、オブジェクトの呼び出し後にメソッドによって返された値を再割り当てする必要があります。たとえば、 NSMutableString は再割り当てなしで直接変更でき
ここに画像の説明を挿入
ます2 つのクラス メソッドの違いは、一方には stringby プレフィックスがあり、もう一方にはプレフィックスがないことです。a = [a stringByAppendingString:@"iii"];

3. 日付と時刻

OC は、これらを処理するための NSDate オブジェクトと NSCalendar オブジェクトを提供します。
まず NSDate を紹介しましょう。
ここに画像の説明を挿入

4. 日付フォーマッタ

当社の日付フォーマッタはクラス フォーマッタとカスタム フォーマッタに分かれています
ここに画像の説明を挿入

5.タイマー

ここはタイマーの作者もまだ理解できていないので、分かり次第追記します。

6. オブジェクトのコピー

オブジェクトのコピーも copy メソッドと MutableCopy メソッドに分かれています。copy メソッドは不変の文字列を返し、mutable は変更可能な文字列を返します。次に、コピーを取得して、元のオブジェクトに影響を与えることなく変更します。
例:
ここに画像の説明を挿入
ここでは、コピーしたオブジェクトが変更できることがわかります。しかし、私たちが自分で作成したクラスはこのメソッドを呼び出すことができません、オブジェクトを正常にコピーするには、copyWithZone メソッドをオーバーライドする必要があります。

オブジェクト自体をコピーするためにオブジェクトの copy メソッドを呼び出すと、プログラムの最下層が実際に copyWithXxxx: メソッドを呼び出して、実際のコピー作業を完了します。copy が実際に返すのは、copyWithXxxx: メソッドの戻り値です。mutableCopyWithZone についても同様です。

ディープコピーとシャローコピーは私たちの焦点の1つです、ここで浅いコピーの定義を確認します。オブジェクトのメンバ変数がポインタ変数の場合、プログラムがポインタが指すオブジェクトを実際にコピーするのではなく、ポインタのアドレスをコピーするだけの場合、この方法は浅いコピーと呼ばれます。
つまり、カスタム クラスの copyWithZone メソッドを書き換える場合、実際にはディープ コピーは実行されません。これは、コピーされたオブジェクトに類似した NSString 型のメンバー変数が、コピーされた変数の実際のポインティング オブジェクトと同じであるためです

ここでの私たちの解決策は、ポインタ型の各メンバ変数を再帰的にコピーします。
ここに画像の説明を挿入

ここで copy 属性について簡単に説明します。実際、その機能は、set メソッドを使用してメンバー変数に値を割り当てるときに、プログラムが copy メソッドを呼び出すことです。違法な変更を避けるために、コピーされた不変コピーをオブジェクトに渡します

7、配列

ここで覚えておく必要があるのは、配列クラスにパラメータを渡すメソッドが一般的に使用されるということです。arrayWithObjects:
次に、コレクション クラスの要素をトラバースする方法を見てみましょう。ここでは 2 つのメソッドを紹介します。より一般的に使用されるメソッドは、 for...in メソッドです
ここに画像の説明を挿入

変数配列のメソッドについては、直接呼び出しを行います。
ここに画像の説明を挿入

8、セット

コレクションを見て、要素をコレクションに追加する方法はsetWithObjects:です。

set を使用するときに注意する必要があるのは、通常、ハッシュ メソッドを書き換えることです。セット内の 2 つの要素が等しいかどうかを判断する基準は、メソッド isEqual が Yes を返し、2 つのオブジェクトのハッシュ メソッドの戻り値も等しいため、set は 2 つのオブジェクトが等しいと判断するからです。通常、ハッシュ メソッドを次のコードで書き換えます。
ここに画像の説明を挿入

9、辞書

辞書をリンクされたリストと考えることができます。彼はキーと値を持っており、それらにはマッピング関係があり、キーを使用して値を見つけます。
ここに画像の説明を挿入
ここで、辞書の値には必ずしも基本型変数が格納されるわけではなく、他のカスタム クラスも格納されることがわかります。

これは、作成者が以前に遭遇した問題につながります:
モデル クラスが定義されており、そのサブクラスが xiyoumobileperson です。xiyoumobileperson クラスを指定すると、
ここに画像の説明を挿入
その中にいくつかのメンバー変数があります。モデル クラスには mutablearray というプロパティがあるため、モデル クラス オブジェクトを作成し、
ここに画像の説明を挿入
ドット構文を使用して内部の可変配列プロパティにオブジェクトを追加できます。ここでのオブジェクトに注意してください。基本型である必要はありません。上記の辞書の値と同様に、カスタム クラスにすることもできます。

ここに画像の説明を挿入

上記のようにカスタム クラスを配列に追加すると、メソッドを呼び出してカスタム クラス内のオブジェクトにアクセスできます。配列に要素を追加する前に、次の操作を行うことに注意してください。最初にカスタム クラス オブジェクトを作成し、次に arrayWithObjects: メソッドを使用してオブジェクトを配列に追加する必要があります。

ここで、配列を走査する方法について説明します。
ここに画像の説明を挿入
要素を走査したい場合、配列には C 言語と同じ添え字が付いています。最初に添え字に対応するオブジェクトを見つけるか、for...in メソッドを使用します。
また、配列内の要素がカスタム クラスの場合、メソッドを呼び出してカスタム クラスのメンバー変数を取得する必要があることにも注意してください。

おすすめ

転載: blog.csdn.net/weixin_72437555/article/details/130545526