0

メソッド loadImage を持つクラス RemoteImageLoader があります。

- (void) loadImage: (NSString*) url setTarget:(NSData **)target;

典型的なメソッドのように、間接的に NSData* を返す必要があるため、ここでは NSData** を使用しました。

- (BOOL)save:(NSError**)

メソッドは実際には別の非同期メソッドを呼び出すため、後でアクセスできるように、ターゲットをメンバー変数として保存する必要があります。しかし、NSData ** メンバー変数を定義すると、次のようになります。

@interface RemoteImageLoader : NSObject    
@property NSData** target;
@end

コンパイラは、「明示的な所有権のない非 const 型 'NSData*' へのポインタ」と不平を言います。私はグーグルでいくつかの検索を行いましたが、答えが見つかりません。誰でもこれで私を助けることができますか?どうもありがとう

そして、宣言を次のように置き換えようとしました

@interface RemoteImageLoader : NSObject    
@property NSData * __autoreleasing * target;
@end

しかし、問題はまだ存在します

4

4 に答える 4

1

あなたのメソッド署名が問題を引き起こすと思います。呼び出し元は、メソッドが返されるとすぐに、ポイント先のポインターが満たされていると想定する可能性が非常に高くなります。同様に、長い間有効ではないスタック変数のアドレスを渡す可能性が非常に高いです。最後に、このメソッドでは、指しているポインターに値が入力されたことを呼び出し元が知る手段が提供されていません。

おそらく、呼び出し元から完了ブロックを受け取ったほうがよいでしょう。完了ブロックは、引数として NSData ポインターを受け取ります。何かのようなもの:

- (void) loadImage: (NSString*) url completionHandler:(void (^)(NSData* data))block;

これは、あなたが使用していると思われる基礎となるフレームワーク API も反映しています。これは、「インピーダンスの不一致」を減らすのに常に適しています。

コンパイラから発生している特定の狭い問題については、に割り当てたときに保持と解放を発行する必要があるかどうかをコンパイラが認識できないことが問題であると思われます*target。指すポインターの所有権特性を明示的に宣言する必要があります。現時点では確認できませんが、 as として宣言する__strong NSData** targetとうまくいくと思います。つまりtarget、ポインターを所有することはできないため、それが指しているものが所有されているかどうかには関心がありません。NSData*どのポイントへのポインターが、それが指すオブジェクトをtarget所有しているかに関心があります。NSData

于 2012-05-09T07:18:32.253 に答える
1

コードを見ないと何をしようとしているのかわかりませんが、なぜNSDataオブジェクトへのポインターを作成しようとしているのでしょうか (これは へのポインターNSDataです)。ポインターへのポインターを作成しているため、おそらくエラーが発生しています。ポインターの 1 つを削除して、何が起こるかを確認してください。

于 2012-05-09T03:28:41.380 に答える
1

ARC Transition Notesでは、__autoreleases を使用して、NSData および NSError オブジェクトへの間接ポインターを宣言することをお勧めします。(NSData * __autoreleasing *)target;

__autoreleasing は、自動解放されたオブジェクトのインスタンスを返すようコンパイラに指示するライフタイム修飾子として知られています。

このため、メソッド シグネチャを書き直す必要があります。

- (void) loadImage: (NSString*) url setTarget:(NSData* __autoreleasing *)target;

__autorelease オブジェクトの寿命は非常に短いことに注意してください。NSData** を __strong として宣言し、デフォルトの __autoreleases をオーバーライドして有効期間を延ばします。

于 2012-05-09T03:30:11.590 に答える
0

一般に、ARCの外部でこの種のことを行うときは、次のようなことを行います。

NSData* returnedParm;
[someObj doSomething:&returnedParm];

発信者側。上記に相当するものは見当たりませんreturnedParm。(私はこれをARCで試したことがありませんが、基本は同じである必要があると思います。)

非オブジェクトへのポインタを宣言するのと同じようにプロパティをNSData**宣言すると、保持されません(保持するオブジェクトがないため)。

私の推測では、関数のプロトタイプを次のように作成する必要があります。

-(void)doSomething:(NSData* __autoreleasing*)theReturnParm

を使用して、その関数内でそれに割り当て*theReturnParm = something;ます。

次に、呼び出し側でreturnedParm、自動解放された値として自分を使用します(したがって、それを保持したい場合は、比較的迅速にstrongポインターに割り当てる必要があります)。

于 2012-05-09T20:22:25.450 に答える