6

Objective-C コンテキストでファクトリ メソッドを使用する目的は何ですか?

Objective-C でのファクトリ メソッドの使用について少し混乱していますか? そうすることの有用性は何ですか?

Objective-Cでファクトリメソッドを使用する例は何ですか?

少し混乱しています。どんな説明でも役に立ちます!

4

2 に答える 2

9

ファクトリ メソッドは、新しく作成され初期化されたオブジェクトを返す任意のクラスまたはインスタンス メソッドです。

より厳密な Objective-C コンテキストでの「クラス ファクトリ メソッド」は、名前がclass .. で始まり、接頭辞が取り除かれ、最初の文字が小文字になっているクラスClassの任意のクラス メソッドです。クラスの例:Foo

+(Foo*) fooWithParam:(NSDictionary*)param;

クラスファクトリ メソッドを使用する理由の 1 つは、利便性のためです。クラスがあるFoo場合、通常の方法で次のように作成できます。

Foo* foo = [[Foo alloc] initWithParam:param];

便利なクラス ファクトリ メソッドを次のように使用できるようになりました。

Foo* foo = [Foo fooWithParam:param];

ただし、クラス ファクトリ メソッドが役立つ理由は他にもあります。

たとえば、initWithParam:メソッドが失敗する可能性があるとします。次に、これがどのように処理されるべきかについて多くの混乱があります: init 内で例外をスローする必要がありますか? それとも戻るべきnilですか?コミュニティでの正しいアプローチについては論争があります。どちらのアプローチにも、避けられないメモリ リークなどの微妙な問題があります。

したがって、このような場合の最も合理的なアプローチは、エラー パラメータを指定してクラス ファクトリ メソッドを使用することです。ここでは、次のように Foo オブジェクトを取得します。

NSError* error;
Foo* foo = [Foo fooWithParam:param error:&error];

ここでのルールは次のとおりです: fooが nil の場合、エラーがあり、出力パラメーターerrorを使用してエラーに関する詳細情報を取得できます。

if (foo) {
    ...
}
else {
    NSLog(@"Error: %@", error);
}

通常、実装は次のようになります。

+ (Foo*) fooWithParam:(NSDictionary*)param error:(NSError**error) {
    if ([param count] < 1) {
        // invalid parameters
        if (error) {                 
            NSError* error = [NSError errorWithDomain:@"Foo" code:-1000 userInfo: ...];            
        }
        return nil;
    }
    return [[self alloc] initWithParam:param]; // won't fail
}

もう 1 つの理由は、「クラス クラスター」を実装することです。これは基本的に、クラス ファクトリ メソッドがクラスのサブクラスを返すことを意味します。例はNSStreamクラスです。

NSInputStreamクラスにはクラス ファクトリ メソッドがあります。

+ (id)inputStreamWithFileAtPath:(NSString *)path;

これは、 の特殊なクラスを返しますNSInputStream


ARC の前の時代には、重要な詳細があります。

クラス ファクトリ メソッドから返されるオブジェクトは「自動解放」されます。つまり、オブジェクトを受け取るクライアントはそれを所有していないため、オブジェクトを解放する必要はありません。

現在、ARC ではこれらの詳細がぼやけています。これらのオブジェクトを手動で解放する必要はありません。オブジェクトが実際に解放される方法と時期も、コンパイラの最適化の対象となります。

于 2013-10-18T13:56:36.303 に答える