LoginSignup
7
7

More than 5 years have passed since last update.

ブロック内でプリミティブ型のインスタンス変数にアクセスする

Last updated at Posted at 2013-08-07

ARC環境のObjective-Cでブロック内でインスタンス変数にアクセスする場合のメモ。
ポインタ変数ならば__block修飾子を使ってretain cycleを回避すればいいのだけど、変数が整数や真偽値などのプリミティブ型だった場合機能しないので以下のように参照を使う。

main.m
@interface SomeClass () {
  BOOL _flag;
}
main.m
[self performBlock:^(id sender) {
  // retain cycle が起きる
  _flag = YES;
} afterDelay:(NSTimeInterval)]
main.m
__block BOOL __flag = _flag
[self performBlock:^(id sender) {
  // ポインタではないので機能しない
  __flag = YES;
} afterDelay:(NSTimeInterval)]

※Ushioさんのご指摘を受けたため修正しました。
ブロック内にインスタンス変数へのポインタをキャプチャしてしまうとselfが破棄されたかどうかの判断がつかないそうです。以下は、KVアクセッサを使ってインスタンス変数にブロック内でアクセスする方法です。

main.m
__block __weak typeof(self) __self = self;
[self performBlock:^(id sender) {
  // KV使ってインスタンス変数にアクセスする
  [__self setValue:YES forKey:@"_flag"];
  BOOL flag = [__self valueForKey:@"flag"] boolValue];
} afterDelay:(NSTimeInterval)]

7
7
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7