block

来源:互联网 发布:大型投资理财网站源码 编辑:程序博客网 时间:2024/06/08 08:41

/*

     如果【block内部】使用【外部声明的强引用】访问【对象A,那么【block内部】会自动产生一个【强引用】指向【对象A

     如果【block内部】使用【外部声明的弱引用】访问【对象A,那么【block内部】会自动产生一个【弱引用】指向【对象A

 */




1.指向函数的指针

void printPodium()

{

    printf("Chris Froome\n");

    printf("Richie Porte\n");

    printf("Fabio Aru\n");

}


int main(int argc,constchar * argv[])

{

    // (*podiumP)代表podiumP是一个指向函数的指针

    // podiumP    :代表指针变量的名称,区分

    // (*podiumP) :代表将来指向一个函数

    // void : 代表将来指向的函数没有返回值

    // ()   : 代表将来指向的函数没有参数


    void (*podiumP) ();

    podiumP = printPodium;

    printPodium();

}


///////

int sum(int value1,int value2)

{

    return value1 + value2;

}


int minus(int value1,int value2)

{

    return value1 - value2;

}


typedef int (*calculte)(int,int);


// 注意:利用typedefblock起别名,和指向函数的指针一样, block变量的名称就是别名

typedef int (^calculteBlock)(int ,int);


  返回值类型 (^block的变量名)(形参类型列表) = ^(形参列表) {

 // block代码

 };

 block的变量名(实参列表);


int main(int argc,constchar * argv[]) {


    /*

//    int (*sumP)(int, int);

//    sumP = sum;

    calculte sumP = sum;

    NSLog(@"sum = %i", sumP(20, 10));

    

    

//    int (*minusP)(int, int);

//    minusP = minus;

    calculte minusP = minus;

    NSLog(@"minus = %i", minusP(20, 10));

       */

    

//    int (^sumBlock)(int , int );

    calculteBlock sumBlock = ^(int value1,int value2){

        return value1 + value2;

    };

    NSLog(@"sum = %i", sumBlock(20,10));

    

//    int (^minusBlock)(int , int);

    calculteBlock minusBlock = ^(int value1,int value2){

        return value1 - value2;

    };

    NSLog(@"minus = %i", minusBlock(20,10));

    return 0;

}

///////


int main(int argc,constchar * argv[]) {


    // 1.block中可以访问外面的变量

    /*

    int a = 10;

    void (^myBlock)() = ^{

        NSLog(@"a = %i", a);

    };

    myBlock();

     

     int a=10;

     void( ^myBlock)()=^{

       Nslog(@"a= %i",a);

     }

     myBlock();

    */

    

    // 2.block中可以定义和外界同名的变量,并且如果在block中定义了和外界同名的变量,block中访问的是block中的变量

    /*

    int a = 10;

    void (^myBlock)() = ^{

        int a  = 20;

        NSLog(@"a = %i", a);

    };

    myBlock();

     */

    

    // 3.默认情况下,不可以在block中修改外界变量的值

    // 因为block中的变量和外界的变量并不是同一个变量

    // 如果block中访问到了外界的变量, block会将外界的变量拷贝一份到堆内存中

    // 因为block中使用的外界变量是copy,所以在调用之前修改外界变量的值,不会影响到blockcopy的值

    /*

    int a = 10;

    NSLog(@"&a = %p", &a);

    void (^myBlock)() = ^{

//        a = 50;

        NSLog(@"&a = %p", &a);

        NSLog(@"a = %i", a);

    };

    a = 20;

    myBlock();

     */

    

    /*

    // 如果想在block中修改外界变量的值,必须在外界变量前面加上__block

    // 如果在block中修改了外界变量的值,会影响到外界变量的值

    __block int a = 10;

    NSLog(@"&a = %p", &a);

    void (^myBlock)() = ^{

        a = 50;

        NSLog(@"&a = %p", &a);

        NSLog(@"a = %i", a);

    };

    myBlock();

    NSLog(@"a = %i", a);

     */

    

    /*

    

//     int a = 10; // 如果没有添加__block是值传递

//     void (*myBlock)() = &__main_block_impl_0( __main_block_func_0, &__main_block_desc_0_DATA, a);

//     (myBlock)->FuncPtr)(myBlock);

    

    // 为什么不加__block不能在block中修改外界变量的值

    int a = 10;

    void (^myBlock)() = ^{

//        a = 10;

        NSLog(@"a = %i", a);

    };

    myBlock();

     */

    

    /*

//    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 a = 10;

    void (^myBlock)() = ^{

        a = 10;

        NSLog(@"a = %i", a);

    };

    myBlock();

     */

    

    

    // block是存储在堆中还是栈中

    // 默认情况下block存储在栈中,如果对block进行一个copy操作, block会转移到堆中

    // 如果block在栈中, block中访问了外界的对象,那么不会对对象进行retain操作

    // 但是如果block在堆中, block中访问了外界的对象,那么会对外界的对象进行一次retain

    

    // 如果在block中访问了外界的对象,一定要给对象加上__block,只要加上了__block,哪怕block在堆中,也不会对外界的对象进行retain

    // 如果是在ARC开发中就需要在前面加上__weak

    __block Person *p = [[Personalloc]init];// 1

    

    // 如果在做iOS开发时,ARC中不这样写容易导致循环引用

//    Person *p = [[Person alloc] init];

//    __weak Person *weakP = p;

    

    NSLog(@"retainCount = %lu", [pretainCount]);

    void (^myBlock)() = ^{

        NSLog(@"p = %@", p);// 2

//        NSLog(@"p = %p", weakP);

        NSLog(@"block retainCount = %lu", [pretainCount]);

    };

    Block_copy(myBlock);

    myBlock();

    

    [p release]; // 1

    

    

    return 0;

}



//////////


    // 2.可以使用copy保存block,这样可以保住block中使用的外界对象的命

    /*

    // 避免以后调用block的时候,外界的对象已经释放了

    Dog *d = [[Dog alloc] init]; // 1

    NSLog(@"retainCount = %lu", [d retainCount]);

    Person *p = [[Person alloc] init];

    p.pBlock = ^{

        // 2

        NSLog(@"%@", d);

    };

    NSLog(@"retainCount = %lu", [d retainCount]); // 2


    // 如果狗在调用block之前释放了,那么程序就会崩溃

    [d release]; // 1

    

    p.pBlock();

    

    [p release];

     */

    

    // 3.注意点: copy block之后引发循环引用

    // 如果对象中的block又用到了对象自己,那么为了避免内存泄露,应该将对象修饰为__block

    __block Person *p = [[Personalloc]init];// 1

    p.name = @"lnj";

    NSLog(@"retainCount = %lu", [pretainCount]);

    p.pBlock = ^{

        NSLog(@"name = %@", p.name);// 2

    };

    NSLog(@"retainCount = %lu", [pretainCount]);

    p.pBlock();

    

    [p release]; // 1






    // 1.如果没有对block进行copy操作,block就存储于栈空间

    // 2.如果对block进行copy操作,block就存储于堆空间

    

    // 3.如果block存储于栈空间,不会对block内部所用到的对象产生强引用

    // 4.如果block存储于堆空间,就会对block内部所用到的对象产生强引用




//////////




block循环引用

    // 定义一个weakSelf,self的弱指针

    // typeof:会自动识别参数的类型

    __weak typeof(self) weakSelf =self;

    

    // 注意:

    // block尽量少使用self,容易造成循环引用

    // block尽量少使用下划线(_)直接访问成员属性

    

    // block机制:block会把里面代码块的所有强指针都强引用

    item.operationBlock = ^(NSIndexPath *indexPath){

        // 点击cell就会调用

        // self:强指针

        // self:间接强引用block

        

        // 获取点击的cell

//        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

        UITableViewCell *cell = [weakSelf.tableViewcellForRowAtIndexPath:indexPath];

        

        // 弹出键盘

        UITextField *textField = [[UITextFieldalloc]init];

        

        [textField becomeFirstResponder];

        

        [cell addSubview:textField];

    };



0 0
原创粉丝点击