2

どのメソッドからでも使用できるグローバル ブロックを作成しようとしています。このブロックがクラスの @properties にアクセスできるようにします。しかし、これを実行しようとすると、バッキング変数 _myVar にアクセスする「宣言されていない識別子の自己の使用」も機能しません。

なぜこれが機能しないのですか?また、任意のメソッドからアクセスできるブロックをどのように回避すればよいでしょうか? ありがとう。

例:

@interface myClass()
@property (nonatomic,assign) BOOL subjectSex;
@end

@implementation

// these returns will get: use of undeclared identifier
int (^myBlock) = ^{

   if(self.subjectSex) return 1;  
   return (!_subjectSex);

}

@end
4

4 に答える 4

2

インスタンス メソッド内でブロックを定義する必要があります。これで、すべてのメソッドがアクセスできる静的ブロック ポインターを持つことができます。ブロックをポインターに割り当てるときは、それをコピーする必要があります。

s_blockPtr = [block copy];

または、 this ポインターを引数としてブロックに送信することもできます。理解するのは簡単ですが、より多くのタイピングが必要になる場合があります。

于 2013-01-31T08:47:37.560 に答える
2

を使用しているので、プロパティへのアクセスとはあまり関係ありませんself。(問題なくアクセスできる他のオブジェクトのプロパティを使用できます。)selfそのスコープには存在しません。メソッドselfの暗黙的なパラメーターです。ブロック定義はメソッド内にないため、という名前の変数はありません( という名前のグローバル変数を定義しない限り、それはおそらく悪い考えです)。selfself

于 2013-01-31T19:44:24.737 に答える
0

ブロックは単なる関数ポインタです。ブロック内のプロパティにアクセスする場合は、プロパティに __block を明示的に設定する必要があります。つまり、これがブロック タイプのプロパティであることをコンパイラに伝える必要があります。ブロックのクロージャを見てみましょう: T1 と T2 の 2 つのスレッドがあるとします。

  //T1 Thread
    void fun(int (*funptr)(int a,int b))
    {
       funptr(2,3);  
    }

    //T2 Thread
    int add(int a,int b)
{
     return a+b;
}
//Main Thread

    fun(&add);
    printf("Hello");

上記のコードから、メイン スレッドのアドレスが 20004 であり、アドレス 20006 の fun を実行し、その fun を関数ポインタとして引数として取り、20064 のアドレスでスレッド T2 の別の関数を指すと仮定します。これは、スレッド T1 と T2 からのコンテキストの切り替えを意味します。 T2スレッドを実行すると、関数はコードセグメントにあるグローバル変数について知りません。これが、それらが異なるスレッドにあるためにアクセスできない理由であり、これがブロックが異なるスレッドで実行されている理由です。それは解決です。

于 2016-03-21T08:01:41.767 に答える
-3

ブロックタイプを宣言することにより、ブロック内の任意のオブジェクトにアクセスできます

 @property(nonatomic,retain) __block NSString *strName;

  dispatch_async(dispatch_get_current_queue(), ^(void)
   {
      self.strName= @"XYZ";
   });
于 2013-01-31T08:23:43.713 に答える