4

Swift プログラミング言語では、

「指定された初期化子は、スーパークラスの初期化子に委任する前に、そのクラスによって導入されたすべてのプロパティが初期化されていることを確認する必要があります。」別の S/O からの引用元

そうしないと、次のようなエラーが表示されます。

プロパティ 'self.baz' が super.init 呼び出しで初期化されていません

Swift で次の Objective-C コードを実装したいと思います。

@interface FooBar : NSObject

@property (nonatomic, readonly) NSString *baz;

@end

@implementataion FooBar

@synthesize baz = _baz;

- (instancetype)initWithString:(NSString *)string {
    self = [super init];
    if (self) {
        _baz = [self parseString:string];
    }
    return self;
}

- (NSString *)parseString:(NSString *)string {
    // Perform something on the original string
    return ...;
}

@end

次の実装では、上記のようにコンパイラ エラーがスローされます。

class FooBar: NSObject {
    let baz: NSString?

    init(string: NSString?) {
        super.init()
        baz = parseString(string)
    }

    private func parseString(string: NSString?) -> NSString? {
        // Perform something on the original string
        return ...;
    }
}

そして、次のことを行うと、次のエラーが表示されます

super.init が自己を初期化する前に、メソッド呼び出し 'parseString' で自己を使用する

class FooBar: NSObject {
    let baz: NSString?

    init(string: NSString?) {
        baz = parseString(string)
        super.init()
    }

    private func parseString(string: NSString?) -> NSString? {
        // Perform something on the original string
        return string;
    }
}

したがって、現在の私の解決策は、プライベート クラス メソッドを使用することです。

class FooBar: NSObject {
    let baz: NSString?

    init(string: NSString?) {
        baz = FooBar.parseString(string)
        super.init()
    }

    private class func parseString(string: NSString?) -> NSString? {
        // Perform something on the original string
        return ...;
    }
}

私の質問は、同じことを達成するためのより良い方法があるか、それともプライベート クラス メソッドが最善のアプローチであるかということです。

4

1 に答える 1

2

あなたが正しく述べたように、コンパイラは「super.initがselfを初期化する前に、メソッド呼び出し 'parseString'でのselfの使用」について不平を言います。selfその理由は、コンパイラが初期化を完了する前に何もアクセスしないようにする必要があるためです。コンパイラは、初期化が完了する前にすべての発信メソッド呼び出しをチェックしたくない (またはできない) ため、完了する前に self の使用を単に禁止します。

幸いなことに、メソッドparseStringはプロパティを変更したりアクセスしたりしたくありません。したがって、それを非インスタンス関数にすることができ、またそうする必要があります。のインスタンスとは何の関係もないFooBarのに、なぜ のインスタンスでしか利用できないのFooBarですか?

staticすでに行ったようにor関数にすることができclassますが、これはまったく問題ありません。

しかし、私はさらに進んで、完全に から移動しFooBarます。そのためのオプションがいくつかあります。

  • 同様Helperに定義するクラスを作成しますclass function
  • Helperとして定義するクラスを作成し、クラスにインスタンスをinstance function作成するか、グローバルなものを作成して、それを init にも渡します。HelperFooBar
于 2015-12-27T13:12:47.837 に答える