block実装原理の詳細
4159 ワード
Arc下block使用時、外部変数参照時、変数が__使用されている場合block修飾と未使用修飾は違いますが、どのような違いがありますか??次はこの問題を詳しく説明します.
多くの人にとって、block内部はどのように実現されているのでしょうか.clangを用いてc++のコードにコンパイルすることで、blockが何なのかを見ることができます.
まずこのような問題を見てみましょう
次のコード
この2つの結果は異なり、最初の出力は10、2番目の出力は30です.
この中で何をしたのか知りたい!C++コードにコンパイルする必要があります.何をしたのか見てみましょう.端末を使用して、mianに移動します.mファイルでは、次のコードclang-rewrite-objc mainを使用する.mこれをコンパイルmainを生成する.cppファイルを開くとmianを開きます.cppはファイルの一番下のmain関数で
{
}
block内部は構造体の関数を呼び出した:static struct main_block_desc_0 { size_t reserved; size_t Block_size; void (copy)(struct __main_block_impl_0, struct main_block_impl_0); void (dispose)(struct __main_block_impl_0*); }
そして、このc++ファイルを分析すると、blockは実際には、構造体を指すポインタコンパイラがblockの内部コードを対応する関数を生成することを知っています.
そしてミアではmでは、通常のint変数を呼び出すと、伝達されたageは実は値伝達であり、_blockはリファレンス伝達!だから、このような結果です!
これはblockに対する基礎的な認識で、次のブログでは、mrcとarcがblockを使う違いを紹介します.読者に役に立つことを望んでいます.
多くの人にとって、block内部はどのように実現されているのでしょうか.clangを用いてc++のコードにコンパイルすることで、blockが何なのかを見ることができます.
まずこのような問題を見てみましょう
<!-- lang: cpp --> int age = 10; void (^block)() = ^{ NSLog(@"%d",age); }; age = 30; block();//10
次のコード
<!-- lang: cpp --> __block int age = 10; void (^block)() = ^{ NSLog(@"%d",age); }; age = 30; block();//30
この2つの結果は異なり、最初の出力は10、2番目の出力は30です.
この中で何をしたのか知りたい!C++コードにコンパイルする必要があります.何をしたのか見てみましょう.端末を使用して、mianに移動します.mファイルでは、次のコードclang-rewrite-objc mainを使用する.mこれをコンパイルmainを生成する.cppファイルを開くとmianを開きます.cppはファイルの一番下のmain関数で
<!-- lang: cpp -->
int main(int argc, const char * argv[])
{
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
__attribute__((__blocks__(byref))) __Block_byref_age_0 age = {(void*)0,(__Block_byref_age_0 *)&age, 0, sizeof(__Block_byref_age_0), 10};
void (*block)() = (void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_age_0 *)&age, 570425344);
(age.__forwarding->age) = 30;
((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block); } return 0;
}
block内部は構造体の関数を呼び出した:static struct main_block_desc_0 { size_t reserved; size_t Block_size; void (copy)(struct __main_block_impl_0, struct main_block_impl_0); void (dispose)(struct __main_block_impl_0*); }
そして、このc++ファイルを分析すると、blockは実際には、構造体を指すポインタコンパイラがblockの内部コードを対応する関数を生成することを知っています.
そしてミアではmでは、通常のint変数を呼び出すと、伝達されたageは実は値伝達であり、_blockはリファレンス伝達!だから、このような結果です!
これはblockに対する基礎的な認識で、次のブログでは、mrcとarcがblockを使う違いを紹介します.読者に役に立つことを望んでいます.