zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Java开发web的几种开发模式
    Tomcat7.0安装配置
    Apache与Tomcat 区别联系
    编写 Window 服务程序
    系列文章--SharePoint 开发教程
    Google Chrome浏览器调试功能介绍
    Chrome的JS调试工具
    Google Chrome 调试JS简单教程[更新]
    ASP.NET常用标准配置web.config
    WINDOWS下kill进程的命令
  • 原文地址:https://www.cnblogs.com/yaowen/p/7436375.html
Copyright © 2011-2022 走看看