Block

os4.0系统已开始支持block

它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似

 

block其实就是一个函数指针,block可以看做是匿名函数的函数指针来对待。

 

Block会捕获外部变量,但是当你试图在Block里面修改捕获的外部变量时。就是出现编译错误,解决的一种办法是将外部变量使用 __block 修饰符修饰。

 

Block循环引用

在实际项目中对于Block最常见的问题应该是循环引用。如果Block中使用了 __strong 修饰符的对象,那么当block从栈复制到堆时,该对象为Block所持有。这样容易造成循环引用,

编译器来说, _obj 变量只不过是对象的成员变量罢了。

解决的方法便是便是通过 __weak 修饰符来修饰会被Block捕获的变量: 

关于Block的应用:

 

block  属性,一般用  copy  修饰;

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

    如果对 block 进行 copy 操作, block 就存储于堆空间 --- 强引用

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

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

注意 :由于使用了  copy  修饰,如果  block  中调用了  block  属性的对象,就会造成循环引用

 

了避免循环引用,需要对对象进行弱引用修饰:

xxx *x = [[xxx alloc] init]; 

// 1、修饰方法1 //
 __unsafe_unretained typeof(x) weakx = x;
 // 2、修饰方法2  
 __block typeof(x) weakx = x;  
 x.testBlock = ^{  [weakx run];  
 };

 简单应用

    int(^getSum)(int,int) = ^(int num1,int num2) {
        return num1 +num2;
    };
    
    int sum = getSum(10,20);
    NSLog(@"计算结果:%d",sum);

  

block传值

 

other.h

 

#import <Foundation/Foundation.h>
@interface Other : NSObject
typedef void (^myBlock)(NSString *str);
@property (nonatomic, copy) myBlock block;
- (instancetype)initWithBlock:(myBlock)block;
@end

  
other.m

#import "Other.h"
@implementation Other
- (instancetype)initWithBlock:(myBlock)block{
    self = [super init];
        if (self.block=block) {
    
            self.block(@"abcxxx");
    
        }
        return self;
}
@end

  调用

#import "ViewController.h"
#import "Other.h"
@interface ViewController ()
@property (nonatomic, copy) NSString *tempStr;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    Other *other = [[Other alloc]initWithBlock:^(NSString *str) {
        self.tempStr = str;
    }];
    
    NSLog(@"传来的结果是:%@",self.tempStr);
}
@end

  

posted @ 2015-12-08 20:49  若云  阅读(398)  评论(0编辑  收藏  举报