zoukankan      html  css  js  c++  java
  • Object-c : block需要注意的几点问题

    摘自:http://www.cnblogs.com/ltpblog/p/3684127.html

     Date : 2015-12-4

    1. Block定义

    1) 说明:

    a. Block是OC中的一种数据类型,在iOS开发中被广泛使用
    b. ^是Block的特有标记
    c. Block的实现代码包含在{}之间
    d. 大多情况下,以内联inline函数的方式被定义和使用
    e. Block与C语言的函数指针有些相似,但使用起来更加灵活
     
    2)  格式:
    (返回类型)(^块名称)(参数类型) = ^(参数列表) {代码实现}
    注:如果没有参数,等号后面的参数列表可以删除。
     
    3)例子:
    (void) (^myBlock)(int, int) = ^(int a, int b) {
      return a + b;
    }
     
    2. Block需要注意的问题

    问题一:

    Block可以使用在定义之前声明的局部变量

    int i = 10;

    void(^myBlock)() = ^{

        NSLog(@"%d", i);

    };

    i = 100;

    myBlock();

    该段代码的输出结果为10.
    注意:
    a. 在定义Block时,会在Block中建立当前局部变量内容的副本(拷贝)
    b. 后续再对该变量的数值进行修改,不会影响Block中的数值
    c. 如果需要在block中保持局部变量的数值变化,需要使用__block关键字
    d. 使用__block关键字后,同样可以在Block中修改该变量的数值
     

    问题二:

    block可以使用block之前的局部变量,但是不能对其进行修改。

    BOOL flag = NO;

    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        if ([@"王五" isEqualToString:obj] || idx == stopIndex) {

            *stop = YES;

            flag = YES;      // 编译错误!!!

            }

    }];

    上述代码编译时,有语法错误。
    注意:
    1. 默认情况下,Block外部的变量,在Block中是只读的。
    2. 如果需要修改外表变量的值,需要在声明变量时加上__block关键字。
     

    问题三:

    传递对象

    NSString *stopName = @"王五";

    NSArray *array = @[@"张三", @"李四", @"王五", @"赵六"];

    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        NSLog(@"第 %d 项内容是 %@", (int)idx, obj);

        if ([stopName isEqualToString:obj] || idx == stopIndex) {

            *stop = YES;

        }

    }];

    注意:

    为保证Block中的代码正常运行,在将stopName的指针传递给Block时,Block会自动对stopName的指针做强引用。
     

    问题四:

    循环引用

    @property (nonatomic, strong) NSMutableArray *myBlocks;

    #pragma mark 将代码改为调用self的方法

    int(^sum)(int, int) = ^(int x, int y) {

        return [self sum:x y:y];

    };

    [self.myBlocks addObject:sum]; 

    #pragma mark 对象被释放时自动调用

    - (void)dealloc

    {

        NSLog(@"DemoObj被释放");

    }

    注意: 
    1. 循环引用的结果就是对象无法被释放。
    2. 局部变量默认都是强引用的,离开其所在的作用域之后就会被释放。
    3. 使用__weak关键字,可以将局部变量声明为弱引用

    __weak DemoObj *weakSelf = self;

    在Block中引用weakSelf,则Block不会再对self做强引用

    int(^sum)(int, int) = ^(int x, int y) {

        return [weakSelf sum:x y:y];

    };

    推荐:

    ios block常见的错误(一)

    ios block常见的错误(二)——循环引用

    ios block常见的错误(三)——并发编程的block引用

  • 相关阅读:
    HDOJ 1588 Gauss Fibonacci
    HDOJ 1494 跑跑卡丁车
    初识Linux
    大数据教程
    80后上班族
    人际交往,七种心态最惹人讨厌
    商人初步
    分页存储过程
    父母生日
    dephi小技巧
  • 原文地址:https://www.cnblogs.com/KeenLeung/p/5019722.html
Copyright © 2011-2022 走看看