block的简单使用
来源:互联网 发布:打印机,输入端口名称 编辑:程序博客网 时间:2024/05/18 00:00
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
int (^sum)(int, int) = ^(int a, int b) {
return a+b;
};
int a = 2, b = 3;
NSLog(@"%d", sum(a, b));
}
return 0;
}
————————————————————————————————————————————————————————————————————————
typedef block
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
typedef int (^blockType)(int, int);
blockType sum = ^(int a, int b) {
return a+b;
};
int a = 2, b = 3;
NSLog(@"%d", sum(a, b));
}
return 0;
}
————————————————————————————————————————————————————————————————————————
block本身可以copy和release。
但是,block在创建的时候,它的内存默认是分配在栈(stack)上,而不是在堆(heap)上。
他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。
示例:
#import "RootViewController.h"
typedef void (^MyBlock)(void);
@interface RootViewController ()
{
MyBlock _block;
}
@end
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
int value = 1;
_block = ^(void) {
NSLog(@"value: %d", value);
};
// _block = [_block copy];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setFrame:CGRectMake(20, 60, self.view.bounds.size.width-40, 35)];
[button setTitle:@"Test" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (void)buttonClick:(id)sender {
_block(); // 这个方法一旦调用就会引起程序crash: EXC_BAD_ACCESS,解决方法是把_block = [_block copy]; 这行代码取消注释,因为copy会把block从栈上移动到堆上,这样就可以在其他地方调用了
}
- (void)dealloc {
[_block release];
[super dealloc];
}
@end
注:为什么对block常使用copy和release而不使用retain?
因为对于block, 有相应的Block_copy和Block_release, 而没有Block_retain
当然,对于上面block引起的crash问题,是在非ARC环境下需要注意的问题,在ARC下,ARC会自动帮忙做处理
————————————————————————————————————————————————————————————————————————
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
typedef void (^MyBlock)(void);
int value = 1;
MyBlock block = ^(void) {
NSLog(@"value: %d", value);
// value = 2;
};
block(); // 1
value = 2;
block(); // 1
/**
* 这里在调用block()之前,value的值明明已经变成了2的。但是为什么这里会打印1呢?
* 因为在block生成的时候会把value当作常量编码到block中,如果要在block中修改外部变量的值,则会报错
* 解决方法:引用__block标识符,告诉编译器__block所修饰的变量是引用的外部变量
* 请看下面的示例2
*/
}
return 0;
}
————————————————————————————————————————————————————————————————————————
用block实现两个视图控制器之间的传值:
#import <UIKit/UIKit.h>
typedef void (^BlockType1)(NSString *str);
@interface SecodViewController : UIViewController
@property (nonatomic, copy) BlockType1 blockHandler1;
- (void)setBlockHandler1:(BlockType1)blockHandler1;
@property (nonatomic, copy) void (^blockHandler2)(NSString *str);
- (void)setBlockHandler2:(void (^)(NSString *str))blockHandler2;
@end
————————————————————————————————————————————————————————————————————————
// 对象有一个Block属性,然而这个Block属性中又引用了对象的其他成员变量,那么就会对这个变量本身产生强应用,那么变量本身和他自己的Block属性就形成了循环引用
// bad
- (void)loopTest {
self.myBlock = ^{
if (self.blockHandler3) {
self.blockHandler3(self.student);
}
};
self.myBlock();
[self.navigationController popViewControllerAnimated:YES];
}
// ok
- (void)loopTest {
__block SecodViewController *_self = self;
self.myBlock = ^{
if (_self.blockHandler3) {
_self.blockHandler3(_self.student);
}
};
self.myBlock();
[self.navigationController popViewControllerAnimated:YES];
}
// ok
- (void)loopTest {
__block typeof(self) weakSelf = self;
self.myBlock = ^{
if (weakSelf.blockHandler3) {
weakSelf.blockHandler3(weakSelf.student);
}
};
self.myBlock();
[self.navigationController popViewControllerAnimated:YES];
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
int (^sum)(int, int) = ^(int a, int b) {
return a+b;
};
int a = 2, b = 3;
NSLog(@"%d", sum(a, b));
}
return 0;
}
————————————————————————————————————————————————————————————————————————
typedef block
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
typedef int (^blockType)(int, int);
blockType sum = ^(int a, int b) {
return a+b;
};
int a = 2, b = 3;
NSLog(@"%d", sum(a, b));
}
return 0;
}
————————————————————————————————————————————————————————————————————————
block本身可以copy和release。
但是,block在创建的时候,它的内存默认是分配在栈(stack)上,而不是在堆(heap)上。
他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。
示例:
#import "RootViewController.h"
typedef void (^MyBlock)(void);
@interface RootViewController ()
{
MyBlock _block;
}
@end
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
int value = 1;
_block = ^(void) {
NSLog(@"value: %d", value);
};
// _block = [_block copy];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setFrame:CGRectMake(20, 60, self.view.bounds.size.width-40, 35)];
[button setTitle:@"Test" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (void)buttonClick:(id)sender {
_block(); // 这个方法一旦调用就会引起程序crash: EXC_BAD_ACCESS,解决方法是把_block = [_block copy]; 这行代码取消注释,因为copy会把block从栈上移动到堆上,这样就可以在其他地方调用了
}
- (void)dealloc {
[_block release];
[super dealloc];
}
@end
注:为什么对block常使用copy和release而不使用retain?
因为对于block, 有相应的Block_copy和Block_release, 而没有Block_retain
当然,对于上面block引起的crash问题,是在非ARC环境下需要注意的问题,在ARC下,ARC会自动帮忙做处理
————————————————————————————————————————————————————————————————————————
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
typedef void (^MyBlock)(void);
int value = 1;
MyBlock block = ^(void) {
NSLog(@"value: %d", value);
// value = 2;
};
block(); // 1
value = 2;
block(); // 1
/**
* 这里在调用block()之前,value的值明明已经变成了2的。但是为什么这里会打印1呢?
* 因为在block生成的时候会把value当作常量编码到block中,如果要在block中修改外部变量的值,则会报错
* 解决方法:引用__block标识符,告诉编译器__block所修饰的变量是引用的外部变量
* 请看下面的示例2
*/
}
return 0;
}
————————————————————————————————————————————————————————————————————————
用block实现两个视图控制器之间的传值:
#import <UIKit/UIKit.h>
typedef void (^BlockType1)(NSString *str);
@interface SecodViewController : UIViewController
@property (nonatomic, copy) BlockType1 blockHandler1;
- (void)setBlockHandler1:(BlockType1)blockHandler1;
@property (nonatomic, copy) void (^blockHandler2)(NSString *str);
- (void)setBlockHandler2:(void (^)(NSString *str))blockHandler2;
@end
————————————————————————————————————————————————————————————————————————
// 对象有一个Block属性,然而这个Block属性中又引用了对象的其他成员变量,那么就会对这个变量本身产生强应用,那么变量本身和他自己的Block属性就形成了循环引用
// bad
- (void)loopTest {
self.myBlock = ^{
if (self.blockHandler3) {
self.blockHandler3(self.student);
}
};
self.myBlock();
[self.navigationController popViewControllerAnimated:YES];
}
// ok
- (void)loopTest {
__block SecodViewController *_self = self;
self.myBlock = ^{
if (_self.blockHandler3) {
_self.blockHandler3(_self.student);
}
};
self.myBlock();
[self.navigationController popViewControllerAnimated:YES];
}
// ok
- (void)loopTest {
__block typeof(self) weakSelf = self;
self.myBlock = ^{
if (weakSelf.blockHandler3) {
weakSelf.blockHandler3(weakSelf.student);
}
};
self.myBlock();
[self.navigationController popViewControllerAnimated:YES];
}
0 0
- block的简单使用
- block的简单使用
- block的简单使用
- Block的简单使用
- BLOck的简单使用
- 简单的block使用
- OC block的简单使用
- OC-简单的使用BLOCK
- iOS-Block的简单使用
- block结构的简单使用
- 01-Block的简单使用
- iOS - block的简单使用
- iOS Block的简单使用
- iOS开发 block的简单使用
- IOS Block代码块的简单使用
- IOS Block代码块的简单使用
- iOS 关于block的简单使用
- block传值的简单使用
- JAVA使用JDBC连接MySQL数据库
- vector 插入的时候就排序
- Dummy output - No Sound Card Detected(转)
- Java解析XML汇总(DOM/SAX/JDOM/DOM4j/XPath)
- 下拉框自动填充文本框
- block的简单使用
- java科学计数法
- c语言练习题 2-1 正整数打印
- Bootstrap学习:字型图标
- DHCP工作过程详解
- Ubuntu12.04 安装VMware9全过程
- 字符串string与char*之间的相互转换
- mysql explain索引优化详解
- Multi-Master Replication Manager for MySQL