0

そのため、NSOperationのサブクラスの初期化子を作成しようとしています。NSOperationを使用するのはこれが初めてです。私のNSOperationサブクラスは次のようになります。

.h
@property (nonatomic, copy) NSString *fileName;

.m
@synthesize fileName = _fileName;


- (id)initWitFileName:(NSString *)fileName  {
    if (self = [super init]) {
        _fileName = fileName;
    }
    return self;
}

- (void)dealloc {
    [_fileName release];
    [super dealloc];
}

- (void)main {
  // do long task
}

したがって、独自の初期化子を作成するときは、オブジェクトの状態がinitメソッドで決定されていないため、自分でivarを設定する必要があると思いました。したがって、初期化子ではアクセサーを使用しません。mainメソッドを実行すると、メモリのアクセス不良とクラッシュが発生します。ただし、私のinitメソッドで、代わりにこれを行うと、次のようになります。

- (id)initWitFileName:(NSString *)fileName  {
        if (self = [super init]) {
            _fileName = [fileName retain];
        }
        return self;
    }

クラッシュしません。何が正しいですか?この2番目のケースでは、アクセサーが(コピー)であるため、メモリを解放しないと思います。それとも、アクセサーを使用していないため、initWithFileNameメソッドに+1がないために、fileNameオブジェクトが基本的に割り当て解除されますか?ありがとう!

4

3 に答える 3

1

2つ目は近いですが、次のとおりです。

- (id)initWitFileName:(NSString *)fileName  
{
    if (self = [super init]) {
        _fileName = [fileName copy];
    }
    return self;
}

NSString*プロパティは一般的に。で定義されるため、より一般的(nonatomic, copy)です。

これは、呼び出し元が実際にを渡し、NSMutableString後で値を変更した場合の問題や意図しない結果を回避するために行われます。

于 2012-07-27T01:12:33.277 に答える
0

プロパティのセットを使用する場合@synthesizeは、オブジェクトのゲッターとセッターを生成します。これにより、次のようなメソッドを使用できます

[self setFilename:@"MyFile.txt"]

また

self.filename = @"MyFile.txt"

上記の両方の行はまったく同じように機能し、次のように実装される可能性があります。

- (void)setFilename:(NSString *)string {
    _filename = [string copy];
    // Or, for a retained property:
    // _filename = [string retain];
}

この実装は非常に単純化されています。実際のセッターが使用するロジックの理解を深めるには、以下のidzのコメントを参照してください。


上記の例では、生成された関数ではなく、単に=演算子を使用しています。

_fileName = fileName;

_fileNameこのため、アドレスをに設定するだけですfileNamesynthesizeプロパティは重要ではなく、ここで違いはありません。

あなたの説明:

アクセサーを使用していないため、initWithFileNameメソッドに+1がないために、fileNameオブジェクトが基本的に割り当て解除されますか?

正確に正しいです。copyシンセサイザーで使用されるプロパティを適切に複製するには、次を使用します。

_fileName = [fileName copy];
于 2012-07-27T01:21:25.557 に答える
0

アイデア1:ARCを使用します。ARCでは、ivarを強力と宣言してから、合成セッターを使用するか、ivarを直接割り当てます。保持が追加され、すべてが順調になります。

アイデア2:保持を使用します。何らかの理由でARCを使用できない場合、なぜNSStringをコピーではなく保持として宣言しないのですか?不変のものの同じインスタンスを保持することは問題ありません。(両方のクラスがそれを実行していることを理解している限り、変更可能なものを共有することも役立ちます)。

アイデア3:非アークを使用する必要があり、コピーを使用する必要がある場合は、コピーを使用してivarを設定します。これで、コピーを実行してクラッシュを修正できます。現在のように、コードは渡された文字列にハンドルをコピーしていますが、その内容はコピーしていません。渡された文字列は割り当て解除され、クラスはゾンビでスタックします。_filename=[文字列コピー];と言うことができます。他の人が示唆しているように。

補足として、self =[superinit];を呼び出します。オーバーライドされたinitメソッド内で正しいです。独自のinitバリアントを作成しているので、self =[selfinit];と呼ぶ方が適切だと思います。

于 2012-07-27T23:56:00.120 に答える