#import "ViewController.h"
@interface ViewController ()
@end
typedef int (^ MyBlock)(int a,int b);
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//无参数无返回值
void(^myblock)(void) = ^(){
NSLog(@"hello word");
};
myblock();
//带参数无返回值
void(^myblock2)(NSString*,NSString*) = ^(NSString *tempStr,NSString *name){
NSLog(@"%@",tempStr);
};
myblock2(@"doubi",@"who");
//带参数有返回值
NSString *(^myblock3)(NSString *) = ^(NSString *temp){
NSString *result = temp;
result = [NSString stringWithFormat:@":%@",result];
return result;
};
NSLog(@"%@",myblock3(@"hu"));
//利用typedef为Block进行重命名
MyBlock block10 = ^(int a,int b) {
return a+b;
};
block10(3 ,5);
}
@end
1.Block在内存中的位置
根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock, NSMallocBlock。
NSGlobalBlock:类似函数,位于text段;
NSStackBlock:位于栈内存,函数返回后Block将无效;
NSMallocBlock:位于堆内存
NSGlobalBlock,我们只要实现一个没有对周围变量没有引用的Block,就会显示为是它。而如果其中加入了对定义环境变量的引用,就是NSStackBlock。那么NSMallocBlock又是哪来的呢?malloc一词其实大家都熟悉,就是在堆上分配动态内存时。没错,如果你对一个NSStackBlock对象使用了Block_copy()或者发送了copy消息,就会得到NSMallocBlock。这一段中的几项结论可从代码实验得出。
也就得到了下面对block的使用注意点。
对于Global的Block,我们无需多处理,不需retain和copy,因为即使你这样做了,似乎也不会有什么两样。对于Stack的Block,如果不做任何操作,就会向上面所说,随栈帧自生自灭。而如果想让它获得比stack frame更久,那就调用Block_copy(),让它搬家到堆内存上。而对于已经在堆上的block,也不要指望通过copy进行“真正的copy”,因为其引用到的变量仍然会是同一份,在这个意义上看,这里的copy和retain的作用已经非常类似。
#import <Foundation/Foundation.h>
typedef long (^Sum)(int,int);
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...v
Sum sum1 = ^ long (int a, int b) {
return a + b ;
};
NSLog(@"sum1 = %@", sum1);// 打印结果:sum1 = <__NSGlobalBlock__: 0x47d0>
int base = 100;
Sum sum2 = ^ long (int a, int b) {
return base + a + b;
};
NSLog(@"sum2 = %@", sum2); // 打印结果:sum2 = <__NSMallocBlock__: 0xbfffddf8>
Sum sum3 = [sum2 copy];
NSLog(@"sum3 = %@", sum3); // 打印结果:sum3 = <__NSMallocBlock__: 0x902fda0>
NSLog(@"Hello, World!");
}
return 0;
}
网友评论