• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
莉er
博客园    首页    新随笔    联系   管理    订阅  订阅
Objective-C( block的使用)

block

block用来保存一段代码

block的标志:^

block跟函数很像:可以保存代码、有返回值、有形参、调用方式跟调用方法一样

block内部可以访问外面的变量

 默认情况下,block内部不能修改外面的局部变量

给局部变量加上__block关键字,这个局部变量就可以在block内部修改

block助记符 inlineBlock

  <#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {

            <#statements#>

        };

 

 利用typedef定义block类型

 typedef int (^MyBlock)(int, int);

 以后就可以利用MyBlock这种类型来定义block变量

 MyBlock block;

 MyBlock b1, b2;

 

没有返回值、没有形参的block

int main()
{
    // 定义block变量
    void (^myblock)() =^(){
        NSLog(@"-------");
        NSLog(@"-------");
        NSLog(@"-------");
    };
    
    // 如果block没有形参就可以省略后面的小括号()
    void (^llblock)() =^{
        NSLog(@"-------");
        NSLog(@"-------");
        NSLog(@"-------");
    };
    
    // 调用block内部代码
    myblock();
    // 利用block变量调用block内部的代码
    llblock();
    
    return 0;
}

 

 

有形参、有返回值的block

int main()
{
    
    int (^sumblock)(int, int) = ^(int a, int b){
        return a + b;
    };
    
    int c = sumblock(5, 8);
    
    NSLog(@"%d", c);
    
    
    // 用一个block输出n条横线
    void (^lineBlock)(int) =  ^(int n)
    {
        for (int i = 0; i<n; i++) {
            NSLog(@"----------------");
        }
    };
    lineBlock(3);

    return 0;
}

 

 

 以下是借鉴,拷贝的博文

二、内存位置(ARC情况)

  1、block块的存储位置(block块入口地址):可能存放在2个地方:代码区、堆区(程序分5个区,还有常量区、全局区和栈区,对于MRC情况下代码还可能存在栈区。关于分区详细参考:http://www.cnblogs.com/mddblog/p/4405165.html

  情况1:代码区

  不访问处于栈区的变量(例如局部变量),且不访问处于堆区的变量(例如alloc创建的对象)。也就是说访问全局变量也可以。

 

复制代码
/**
  没有访问任何变量
 */
int main(int argc, char * argv[]) {
    void (^block)(void) = ^{
        NSLog(@"===");
    };
    block();
}
复制代码

 

复制代码
/**
  访问了全局(静态)变量
 */
int  iVar = 10;
int main(int argc, char * argv[]) {
    void (^block)(void) = ^{
        NSLog(@"===%d",iVar);
    };
    block();
}
复制代码

  情况2:堆区

  如果访问了处于栈区的变量(例如局部变量),或处于堆区的变量(例如alloc创建的对象)。都会存放在堆区。(实际是放在栈区,然后ARC情况下自动又拷贝到堆区)

复制代码
/**
  访问局部变量
 */
int main(int argc, char * argv[]) {
    int iVar = 10;
    void (^block)(void) = ^{
        NSLog(@"===%d",iVar);
    };
    block();
}
复制代码

  2、注意事项

  代码存放在堆区时,就需要特别注意,因为堆区不像代码区不变化,堆区是不断变化的(不断创建销毁)。因此代码有可能会被销毁(当没有强指针指向时),如果这时再访问此段代码则会程序崩溃。因此,对于这种情况,我们在定义一个block属性时应指定为strong,或copy:

  @property (nonatomic, strong) void (^myBlock)(void); // 这样就有强指针指向它

  @property (nonatomic, copy)  void (^myBlock)(void);  // 并不会在堆区copy一份,原因见 三

  而对于第1种情况(代码存在代码区),使用strong,copy(不会复制一份到堆区)也可以。因此定义block时最好指定为strong(推荐)或copy。

  3、指定为copy后是否会拷贝一份呢?(或者说是浅拷贝还是深拷贝)

    1 copy可变变量:在赋值指针的同时也会复制指针指向的内存区域。深拷贝,例如NSMutableString对象。

    2 copy不可变变量:等同于strong,还是浅拷贝,例如NSString对象。

    因为block是一段代码,即不可变的,所以并不会深拷贝。

 

posted on 2015-08-29 12:12  lier莉儿  阅读(395)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3