0

ブロックを指すプロパティを持つオブジェクトがあります。

typedef void (^ThingSetter)();
@property(nonatomic, strong) ThingSetter setup;

プロパティをブロックで初期化します。私の中でblock私はオブジェクトインスタンスを参照します:

Thing *thing = [[Thing alloc] init];

thing.setup = ^() {

    plainOleCFunction(thing.number);
    [thing doSomethingWithString:@"foobar"];
};

ただし、保持ループに関するコンパイル警告が表示されます。

capturing 'thing' strongly in this block is likely to lead to a retain cycle
block will be retained by the captured object

これを行う正しい方法は何ですか?

ありがとう、ダグ

4

2 に答える 2

4

thing弱い参照として割り当てる必要があります:

Thing *thing = [[Thing alloc] init];
__weak Thing *weakThing = thing;

thing.setup = ^() {

    plainOleCFunction(weakThing.number);
    [weakThing doSomethingWithString:@"foobar"];
};

thingまたは、ブロックにパラメーターとして指定できます。

Thing *thing = [[Thing alloc] init];

thing.setup = ^(Thing *localThing) {

    plainOleCFunction(localThing.number);
    [localThing doSomethingWithString:@"foobar"];
};
thing.setup(thing);
于 2013-02-09T13:53:05.263 に答える
1

ブロック内で「もの」を使用しているため、ブロックが範囲外になるか、ブロック自体がヒープを離れるまで (つまり、誰もそのブロックを強く指していない)、ブロックは「もの」への強力なポインターを維持します。ブロックが最初に移動され、後でコードが実行されるため、ブロックが実行されずに最初に移動された後、ブロックが「もの」へのポインターを失いたくないことは明らかです。

これで、「物」への強力なポインタを維持するブロックがあり、プロパティ「セットアップ」を通じてブロックへの強力なポインタを維持する「物」があります。「もの」もブロックも、ヒープから逃れることはできません。これは、両方への強力なポインター (互いのポインター) が常に存在するためです。これは記憶の「サイクル」と呼ばれます。</p>

答えは、「もの」を弱いものとして宣言することです。

Thing *thing = [[Thing alloc] init];
__弱いもの *弱いもの = もの;

そして、ブロックで「weakThing」を使用します。ブロックには "weakThing" への弱いポインターしかないため、これで問題が解決します。「物」には、プロパティのセットアップを通じてブロックへの強力なポインターがまだありますが、それは問題ありません。

これが役に立ったことを願っています

于 2013-02-09T14:16:35.450 に答える