oc62--block1
// // main.m // Block的应用场景 // typedef void (^workBlock)(); #import <Foundation/Foundation.h> /* void goToWorkPrefix() { NSLog(@"起床"); NSLog(@"穿衣服"); NSLog(@"洗漱"); NSLog(@"喝早茶"); NSLog(@"驾车去上班"); } void goToWorkSubfix() { NSLog(@"收拾东西"); NSLog(@"驾车回家"); NSLog(@"吃晚饭"); NSLog(@"洗澡"); NSLog(@"睡觉"); } void goToWorkInday1() { goToWorkPrefix(); NSLog(@"认识新同事"); goToWorkSubfix(); } void goToWorkInday2() { goToWorkPrefix(); NSLog(@"熟悉公司代码"); goToWorkSubfix(); } void goToWorkInday3() { goToWorkPrefix(); NSLog(@"开始编写代码"); goToWorkSubfix(); } void goToWorkInday4() { goToWorkPrefix(); NSLog(@"应用程序上架"); goToWorkSubfix(); } */ // 当发现代码的前面和后面都是一样的时候, 这个时候就可以使用block void goToWork(workBlock w) { NSLog(@"起床"); NSLog(@"穿衣服"); NSLog(@"洗漱"); NSLog(@"喝早茶"); NSLog(@"驾车去上班"); // 不一样 w(); NSLog(@"收拾东西"); NSLog(@"驾车回家"); NSLog(@"吃晚饭"); NSLog(@"洗澡"); NSLog(@"睡觉"); } void goToWorkInDay1() { goToWork( ^{NSLog(@"认识新同事");} ); } void goToWorkInDay2() { goToWork(^{ NSLog(@"熟悉公司代码"); }); } void goToWorkInDay3() { goToWork(^{ NSLog(@"开始编写代码"); }); } void goToWorkInDay4() { goToWork(^{ NSLog(@"应用程序上架"); }); } /* 找到需要读取的文件 读取文件 操作文件 关闭文件 */ int main(int argc, const char * argv[]) { goToWorkInDay2(); return 0; }
// main.m // Block的注意事项 // 终端进入main.m的目录,执行cc -rewrite-objc main.m ,能够在"磁盘"中看到m文件执行后的C++文件。 #import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { // 1.block中可以访问外面的变量 int a = 10; void (^myBlock)() = ^{ NSLog(@"a = %i", a); }; myBlock(); int a1=10; void( ^myBlock1)()=^{ Nslog(@"a= %i",a1); }; myBlock1(); // 2.block中可以定义和外界同名的变量, 并且如果在block中定义了和外界同名的变量, 在block中访问的是block中的变量 int a2 = 10; void (^myBlock2)() = ^{ int a2 = 20; NSLog(@"a = %i", a2); }; myBlock2(); // 3.默认情况下, 不可以在block中修改外界变量的值 // 因为block中的变量和外界的变量并不是同一个变量 // 如果block中访问到了外界的变量, block会将外界的变量拷贝一份到堆内存中 // 因为block中使用的外界变量是copy的, 所以在调用之前修改外界变量的值, 不会影响到block中copy的值 int a3 = 10; NSLog(@"&a = %p", &a3); void (^myBlock3)() = ^{ //a3 = 50; //不能修改外界的值, NSLog(@"&a = %p", &a3); NSLog(@"a = %i", a3); }; a3 = 20; myBlock(); // 如果想在block中修改外界变量的值, 必须在外界变量前面加上__block // 如果在block中修改了外界变量的值, 会影响到外界变量的值 __block int a4 = 10; NSLog(@"&a = %p", &a4); void (^myBlock4)() = ^{ a4 = 50; NSLog(@"&a = %p", &a4); NSLog(@"a = %i", a4); }; myBlock4(); NSLog(@"a = %i", a4); // int a53 = 10; // 如果没有添加__block是值传递 // void (*myBlock53)() = &__main_block_impl_0( __main_block_func_0, &__main_block_desc_0_DATA, a); // (myBlock53)->FuncPtr)(myBlock53); // 为什么不加__block不能在block中修改外界变量的值 int a5 = 10; void (^myBlock5)() = ^{ // a5 = 10; NSLog(@"a = %i", a5); }; myBlock5(); // a = 10; // 如果加上__block之后就是地址传递, 所以可以在block中修改外界变量的值 // void (*myBlock)() = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, &a, 570425344); // 为什么加了__block就可以在block中修改外界变量的值 __block int a6 = 10; void (^myBlock6)() = ^{ a6 = 10; NSLog(@"a = %i", a6); }; myBlock6(); // block是存储在堆中还是栈中 // 默认情况下block存储在栈中, 如果对block进行一个copy操作, block会转移到堆中 // 如果block在栈中, block中访问了外界的对象, 那么不会对对象进行retain操作 // 但是如果block在堆中, block中访问了外界的对象, 那么会对外界的对象进行一次retain // 如果在block中访问了外界的对象, 一定要给对象加上__block, 只要加上了__block, 哪怕block在堆中, 也不会对外界的对象进行retain // 如果是在ARC开发中就需要在前面加上__weak __block Person *p = [[Person alloc] init]; // 1 // 如果在做iOS开发时, 在ARC中不这样写容易导致循环引用 // Person *p = [[Person alloc] init]; // __weak Person *weakP = p; NSLog(@"retainCount = %lu", [p retainCount]); void (^myBlock7)() = ^{ NSLog(@"p = %@", p); // 2 // NSLog(@"p = %p", weakP); NSLog(@"block retainCount = %lu", [p retainCount]); }; Block_copy(myBlock7); myBlock7(); [p release]; // 1 return 0; }