由浅到深的了解block
来源:互联网 发布:域名未授权 编辑:程序博客网 时间:2024/05/16 10:07
作为IOS开发者来说,你不会用block,真的就不能和其他小伙伴一块玩耍了,block运用随处可见,block这样的语法真的看起来很诡异,那么这个神奇的block(闭包)到底是何方神圣呢?各位看官,不要讲话,保留疑问,先看文章摘要,please静静的感受一下它的用法吧, go!!
本文章的概要
1. block的基本应用
2. block的typedef
3. block的作用
4. block运用过程中出现的问题以及如何规避
5. 深入了解block
- block的基本应用
直观感受block跟函数很像,函数在调用前必须声名
void test3();
int main(int argc,constchar * argv[])
{
@autoreleasepool {
test3();
}
return0;
}
同样的block 同样也需要调用前必须声明
/**
定义了一个有返回值有参数的block
*/
void test3()
{
// 定义一个block计算两个整数的和
int (^sumBlock)(int,int) = ^(int num1,int num2) {
return num1 + num2;
};
int c = sumBlock(10,9);
// 定义一个block计算一个整数的平方
int (^pinfangBlock)(int);
pinfangBlock = ^(int num){
return num * num;
};
pinfangBlock = ^(int num) {
return num +2;
};
int d = pinfangBlock(10);
NSLog(@"d is %d", d);
}
/**
定义了一个没有返回值但有参数的block
*/
void test2()
{
// 定义block变量,存储一段代码,这段代码的功能是能打印任意行数的****
void (^logStarBlock)(int) = ^(int numberOfLines){
for (int i =0; i<numberOfLines; i++) {
NSLog(@"***************");
}
};
logStarBlock(1);
}
/**
定义了一个没有返回值没有参数的block
*/
void test()
{
// 定义简单的block变量
// block跟函数很像:返回值、参数
void (^logStar)() = ^{
NSLog(@"***************");
NSLog(@"***************");
NSLog(@"***************");
};
logStar();
}
- block的typedef
但是如果只是在函数体进行声明,调用,代码看起来不美观,感觉太乱了,所以需要typedef,这才是经常用的一种方式
// 定义一个叫做MyBlock的类型
// 利用MyBlock类型可以定义block变量
// 利用MyBlock类型定义出来的变量,存储的代码必须返回int,必须接受2个int类型的参数
typedef int (^MyBlock)(int,int);
int main(int argc,constchar * argv[])
{
@autoreleasepool {
MyBlock minusBlock = ^(int num1,int num2) {
return num1 - num2;
};
MyBlock multiBlock = ^(int num1,int num2) {
return num1 * num2;
};
multiBlock(10,1);
}
return0;
}
void test()
{
// 定义一个block来计算2个整数的差
int (^minusBlock)(int,int) = ^(int num1,int num2) {
return num1 - num2;
};
// 定义一个block来计算2个整数的积
int (^multiBlock)(int,int) = ^(int num1,int num2) {
return num1 * num2;
};
}
当然你也可以这样
typedef void(^tapBlock)(NSIndexPath*indexPath);
typedef void(^textBlock)(NSIndexPath*indexPath,NSString*text);
typedef void(^pushTextViewBlock)(NSIndexPath*cellIndexPath,NSString*title,NSString*defaultText);
typedef void(^showImageBlock)(NSIndexPath*indexPath,NSArray* imageArr,NSInteger imgIndex);
typedef void(^deletPhotoBlock)(NSIndexPath*indexPath,NSArray*imgArr,NSInteger imgIndex);
typedef void(^scannerBlock)(NSString *scannerType);
typedef void (^SearchStaffBlock)(NSString *backTitle,NSArray *cidArray,int tag);
typedef void(^SearchCustomMobile)(NSString *cidTitle,NSString *title);
@interface CMDynomicCell : UITableViewCell
@property(nonatomic,strong)NSIndexPath* selectIndexPath; //cell所在的indexPath;
@property(nonatomic,strong)textBlock SingleLineText; //单行文本的回调
@property(nonatomic,strong)textBlock NumberText; //数字文本的回调
@property(nonatomic,strong)pushTextViewBlock pushTextView;//多行文本的回调
@end调用self.textBlock=^(NSIndexPath*indexPath,NSString*text){
};
空外一种方式直接在方法上直接使用,这样看起来更加灵活了
-(void)noticeTaskList:(int)userId noticeId:(int)noticeId taskId:(int)taskId success:(void(^)(id object))successBlock fail:(void(^)(NSString* msg))failBlock;
-(void)noticeTaskList:(int)userId noticeId:(int)noticeId taskId:(int)taskId success:(void(^)(id object))successBlock fail:(void(^)(NSString* msg))failBlock{
if(successBlock) {
successBlock(id);
};
if(failBlock) {
failBlock(NSString*);
}
}
调用方式:
[[CMLoginHttpServicesharedInstance]login:usernamecompanyUsername:companyUsernamephone:phonepassword:passwordimei:imeiversionNo:versionNomobileName:mobileNamemobileType:mobileType success:^(id object) {
} fail:^(NSString *msg) {
}];
使用方式总结
3. block的作用
1>重构代码,解耦合
#import <Foundation/Foundation.h>
typedef void (^WorkBlock)();
void goToWork(WorkBlock workBlock)
{
NSLog(@"起床");
NSLog(@"刷牙");
NSLog(@"穿衣服穿鞋");
NSLog(@"出门");
NSLog(@"搭公交");
NSLog(@"抵达公司");
// 实事
// 调用block之前一定要做判断
if (workBlock !=nil) {
workBlock();
}
// 实事
NSLog(@"叮咚叮咚下班了");
NSLog(@"搭公交");
NSLog(@"回家");
NSLog(@"睡觉");
}
/**
模拟星期一上班的具体情况
*/
void goToWorkInDay1()
{
goToWork(^{
NSLog(@"了解项目的需求");
});
}
void goToWorkInDay2()
{
// 实事
goToWork(^{
NSLog(@"熟悉公司以前的代码");
});
// 实事
}
void goToWorkInDay3()
{
// 实事
goToWork(^{
NSLog(@"开始编写代码");
});
// 实事
}
void test(int (^myblock)(int num1,double num2, char num3))
{
}
int main(int argc,constchar * argv[])
{
@autoreleasepool {
//// goToWorkInDay3();
// test(^int(int num1, double num2, char num3) {
//
// });
// WorkBlock block = ^{
// NSLog(@"-------------------");
// };
//
// goToWork(block);
}
return0;
}
2>block 在实现时就会对它引用到的它所在方法中定义的栈变量进行一次只读拷贝,然后在 block 块内使用该只读拷贝。
- (void)testAccessVariable
{
NSInteger outsideVariable = 10;
//__block NSInteger outsideVariable = 10;
NSMutableArray * outsideArray = [[NSMutableArray alloc] init];
void (^blockObject)(void) = ^(void){
NSInteger insideVariable = 20;
KSLog(@" > member variable = %d", self.memberVariable);
KSLog(@" > outside variable = %d", outsideVariable);
KSLog(@" > inside variable = %d", insideVariable);
[outsideArray addObject:@"AddedInsideBlock"];
};
outsideVariable = 30;
self.memberVariable = 30;
blockObject();
KSLog(@" > %d items in outsideArray", [outsideArray count]);
}
输出结果:
3>在使用之前最好判断是否为nil,否则极有可能引起崩溃
参考来源
block注意事项及源代码
http://blog.csdn.net/allison162004/article/details/22850749
http://blog.csdn.net/fengsh998/article/details/38090205
5.深入了解block
以下这篇博客,写的这么这么深入也是没谁了!!
http://blog.devtang.com/2013/07/28/a-look-inside-blocks/
- A look inside blocks: Episode 1
- A look inside blocks: Episode 2
- A look inside blocks: Episode 3
- 对 Objective-C 中 Block 的追探
- LLVM 中 block 实现源码
- objective-c-blocks-quiz
- Blocks
__________________________________________________
6.面试的block问题
Block的定义:
1> Block是OC中得一种数据类型,在iOS开发中被广泛使用.
2> ^是Block的特有标记.
3> Block的实现代码包含在{ }之间.
4> 大多数情况下,以内联inline函数的方式被定义和使用.
5> Block与C语言的指针有些相似,但使用更加灵活.
内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质.编译时,类似宏替代,使用函数体替换调用处的函数名;
Block封装了一段代码,可以在任何时候执行;
Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或者返回值;
苹果官方建议尽量多使用block.在多线程,异步任务,集合遍历,集合排序,动画转场用得很多.
1 什么是block
nt (^yxpBlock)(int, int) =^(int a ) {return a*a ;};
说明:返回值(^语句块名称)(传人参数类型)=^(传人参数){主体};
];
你可以通过使用for循环来达到目的,但是在iOS4中NSArray类有一个使用了代码块的方便方法:enumerateObjectsUsingBlock:。下面是如何使用它:
NSLog(@"%@ card at index %d", object, index);
}];
- 由浅到深的了解block
- block的初级了解
- block的简单了解
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- 由浅到深了解JavaScript类
- Block了解
- iOS巅峰之block(由浅到深)详解
- Andorid 动画介绍
- 嗅探、中间人sql注入、反编译--例说桌面软件安全性问题
- C++ 默认构造函数深度解析
- 【sql server】解决 com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '@P0'.
- JniHelper c++调用安卓代码
- 由浅到深的了解block
- 2015多校联盟
- C#学习笔记之File类
- LINUX+APACHE+MYSQL+PHP安全加固配置说明
- 第12周项目-复数类中的运算符重载
- UVA 11426 GCD - Extreme (II) (欧拉函数)
- MAC窗口管理神器--Moom
- Linux下Oracle GoldenGate(OGG)的配置
- canOpenURL: failed for URL