精华内容
下载资源
问答
  • Block

    千次阅读 2013-07-28 11:38:08
    Block简介Block的创建不带参数的BlockBlock的闭包性closure修改非局部变量Block作为函数的参数定义Block类型总结延伸阅读 本周末微博上朋友发了一个关于block的MV,只能说老外太逗了。大家也可以去看看怎么...


    本周末微博上朋友发了一个关于block的MV,只能说老外太逗了。大家也可以去看看怎么回事: Cocoa Got Blocks。虽然之前也有接触过block,不过没有深入完整的学习过,借此机会来学习一下,顺便翻译几篇block相关的文章,本文是第一篇,算是block的入门。本文的最后延伸阅读给出了4篇相关文章,不出意外的话,本周大家能看到对应的中文版。

    目录:

    • Block简介
    • Block的创建
    • 不带参数的Block
    • Block的闭包性(closure)
    • 修改非局部变量
    • Block作为函数的参数
    • 定义Block类型
    • 总结
    • 延伸阅读

    正文

    Block简介

    我们可以把Block当做Objective-C的匿名函数。Block允许开发者在两个对象之间将任意的语句当做数据进行传递,往往这要比引用定义在别处的函数直观。另外,block的实现具有封闭性(closure),而又能够很容易获取上下文的相关状态信息。

    Block的创建

    实际上,block使用了与函数相同的机制:可以像声明函数一样,来声明一个bock变量;可以利用定义一个函数的方法来定义一个block;也可以将block当做一个函数来调用。

    1. // main.m
    2. #import <Foundation/Foundation.h>
    3.  
    4. int main(int argc, const char * argv[]) {
    5. @autoreleasepool {
    6. // Declare the block variable
    7. double (^distanceFromRateAndTime)(double rate, double time);
    8.  
    9. // Create and assign the block
    10. distanceFromRateAndTime = ^double(double rate, double time) {
    11. return rate * time;
    12. };
    13. // Call the block
    14. double dx = distanceFromRateAndTime(35, 1.5);
    15.  
    16. NSLog(@"A car driving 35 mph will travel "
    17. @"%.2f miles in 1.5 hours.", dx);
    18. }
    19. return 0;
    20. }

    在上面的代码中,利用插入符(^)将distanceFromRateAndTime变量标记为一个block。就像声明函数一样,需要包含返回值的类型,以及参数的类型,这样编译器才能安全的进行强制类型转换。插入符(^)跟指针(例如 int *aPointer)前面的星号(*)类似——只是在声明的时候需要使用,之后用法跟普通的变量一样。

    block的定义本质上跟函数一样——只不过不需要函数名。block以签名字符串开始:^double(double rate, double time)标示返回一个double,以及接收两个同样为double的参数(如果不需要返回值,可以忽略掉)。在签名后面是一个大括弧({}),在这个括弧里面可以编写任意的语句代码,这跟普通的函数一样。

    当把block赋值给distanceFromRateAndTime后,我们就可以像调用函数一样调用这个变量了。

    不带参数的Block

    如果block不需要任何的参数,那么可以忽略掉参数列表。另外,在定义block的时候,返回值的类型也是可选的,所以这样情况下,block可以简写为^ { … }:

    1. double (^randomPercent)(void) = ^ {
    2. return (double)arc4random() / 4294967295;
    3. };
    4. NSLog(@"Gas tank is %.1f%% full",
    5. randomPercent() * 100);

    在上面的代码中,利用内置的arc4random()方法返回一个32位的整型随机数——为了获得0-1之间的一个值,通过除以arc4random()方法能够获取到的最大值(4294967295)。

    到现在为止,block看起来可能有点像利用一种复杂的方式来定义一个方法。事实上,block是被设计为闭包的(closure)——这就提供了一种新的、令人兴奋的编程方式。

    Block的闭包性(closure)

    在block内部,可以像普通函数一样访问数据:局部变量、传递给block的参数,全局变量/函数。并且由于block具有闭包性,所以还能访问非局部变量(non-local variable)。非局部变量定义在block之外,但是在block内部有它的作用域。例如,getFullCarName可以使用定义在block前面的make变量:

    1. NSString *make = @"Honda";
    2. NSString *(^getFullCarName)(NSString *) = ^(NSString *model) {
    3. return [make stringByAppendingFormat:@" %@", model];
    4. };
    5. NSLog(@"%@", getFullCarName(@"Accord")); // Honda Accord

    非局部变量会以const变量被拷贝并存储到block中,也就是说block对其是只读的。如果尝试在block内部给make变量赋值,会抛出编译器错误。

    const-non-local-variables

    以const拷贝的方式访问非局部变量

     

    以const拷贝的方式访问非局部变量,意味着block实际上并不是真正的访问了非局部变量——只不过在block中创建了非局部变量的一个快照。当定义block时,无论非局部变量的值是什么,都将被冻结,并且block会一直使用这个值,即使在之后的代码中修改了非局部变量的值。下面通过代码来看看,在创建好block之后,修改make变量的值,会发生什么:

    1. NSString *make = @"Honda";
    2. NSString *(^getFullCarName)(NSString *) = ^(NSString *model) {
    3. return [make stringByAppendingFormat:@" %@", model];
    4. };
    5. NSLog(@"%@", getFullCarName(@"Accord")); // Honda Accord
    6.  
    7. // Try changing the non-local variable (it won't change the block)
    8. make = @"Porsche";
    9. NSLog(@"%@", getFullCarName(@"911 Turbo")); // Honda 911 Turbo

    block的闭包性为block与上下文交互的时候带来极大的便利性,当block需要额外的数据时,可以避免使用参数——只需要简单的使用非局部变量即可。

    修改非局部变量

    冻结中的非局部变量是一个常量值,这也是一种默认的安全行为——因为这可以防止在block中的代码对非局部变量做了意外的修改。那么如果我们希望在block中对非局部变量值进行修改要如何做呢——用__block存储修饰符(storage modifier)来声明非局部变量:

    1. __block NSString *make = @"Honda";

    这将告诉block对非局部变量做引用处理,在block外部make变量和内部的make变量创建一个直接的链接(direct link)。现在就可以在block外部修改make,然后反应到block内部,反过来,也是一样。

    mutable-non-local-variables

    通过引用的方式访问非局部变量

    这跟普通函数中的静态局部变量(static local variable)类似,用__block修饰符声明的变量可以记录着block多次调用的结果。例如下面的代码创建了一个block,在block中对i进行累加。

    1. __block int i = 0;
    2. int (^count)(void) = ^ {
    3. i += 1;
    4. return i;
    5. };
    6. NSLog(@"%d", count()); // 1
    7. NSLog(@"%d", count()); // 2
    8. NSLog(@"%d", count()); // 3

    Block作为函数的参数

    把block存储在变量中有时候非常有用,比如将其用作函数的参数。这可以解决类似函数指针能解决的问题,不过我们也可以定义内联的block,这样代码更加易读。
    例如下面Car interface中声明了一个方法,该方法用来计算汽车的里程数。这里并没有强制要求调用者给该方法传递一个常量速度,相反可以改方法接收一个block——该block根据具体的时间来定义汽车的速度。

    1. // Car.h
    2. #import <Foundation/Foundation.h>
    3.  
    4. @interface Car : NSObject
    5.  
    6. @property double odometer;
    7.  
    8. - (void)driveForDuration:(double)duration
    9. withVariableSpeed:(double (^)(double time))speedFunction
    10. steps:(int)numSteps;
    11.  
    12. @end

    上面代码中block的数据类型是double (^)(double time),也就是说block的调用者需要传递一个double类型的参数,并且该block的返回值为double类型。注意:上面代码中的语法基本与本文开头介绍的block变量声明相同,只不过没有变量名字。
    在函数的实现里面可以通过speedFunction来调用block。下面的示例通过算法计算出汽车行驶的大约距离。其中steps参数是由调用者确定的一个准确值。

    1. // Car.m
    2. #import "Car.h"
    3.  
    4. @implementation Car
    5.  
    6. @synthesize odometer = _odometer;
    7.  
    8. - (void)driveForDuration:(double)duration
    9. withVariableSpeed:(double (^)(double time))speedFunction
    10. steps:(int)numSteps {
    11. double dt = duration / numSteps;
    12. for (int i=1; i<=numSteps; i++) {
    13. _odometer += speedFunction(i*dt) * dt;
    14. }
    15. }
    16.  
    17. @end

    在下面的代码中,有一个main函数,在main函数中block定义在另一个函数的调用过程中。虽然理解其中的语法需要话几秒钟时间,不过这比起另外声明一个函数,再定义withVariableSpeed参数要更加直观。

    1. // main.m
    2. #import <Foundation/Foundation.h>
    3. #import "Car.h"
    4.  
    5. int main(int argc, const char * argv[]) {
    6. @autoreleasepool {
    7. Car *theCar = [[Car alloc] init];
    8.  
    9. // Drive for awhile with constant speed of 5.0 m/s
    10. [theCar driveForDuration:10.0
    11. withVariableSpeed:^(double time) {
    12. return 5.0;
    13. } steps:100];
    14. NSLog(@"The car has now driven %.2f meters", theCar.odometer);
    15.  
    16. // Start accelerating at a rate of 1.0 m/s^2
    17. [theCar driveForDuration:10.0
    18. withVariableSpeed:^(double time) {
    19. return time + 5.0;
    20. } steps:100];
    21. NSLog(@"The car has now driven %.2f meters", theCar.odometer);
    22. }
    23. return 0;
    24. }

    上面利用一个简单的示例演示了block的通用性。在iOS的SDK中有许多API都利用了block的其它一些功能。NSArray的sortedArrayUsingComparator:方法可以使用一个block对元素进行排序,而UIView的animateWithDuration:animations:方法使用了一个block来定义动画的最终状态。此外,block在并发编程中具有强大的作用。

    定义Block类型

    由于block数据类型的语法会很快把函数的声明搞得难以阅读,所以经常使用typedef对block的签名(signature)做处理。例如,下面的代码创建了一个叫做SpeedFunction的新类型,这样我们就可以对withVariableSpeed参数使用一个更加有语义的数据类型。

    1. // Car.h
    2. #import <Foundation/Foundation.h>
    3.  
    4. // Define a new type for the block
    5. typedef double (^SpeedFunction)(double);
    6.  
    7. @interface Car : NSObject
    8.  
    9. @property double odometer;
    10.  
    11. - (void)driveForDuration:(double)duration
    12. withVariableSpeed:(SpeedFunction)speedFunction
    13. steps:(int)numSteps;
    14.  
    15. @end

    许多标准的Objective-C框架也使用了这样的技巧,例如NSComparator

    总结

    Block不仅提供了C函数同样的功能,而且block看起来更加直观。block可以定义为内联(inline),这样在函数内部调用的时候就非常方便,由于block具有闭包性(closure),所以block可以很容易获得上下文信息,而又不会对这些数据产生负面影响。

    延伸阅读

     

    本文由破船翻译●转载请注明出处●2013-07-0


    本周末微博上朋友发了一个关于block的MV,只能说老外太逗了。大家也可以去看看怎么回事: Cocoa Got Blocks。虽然之前也有接触过block,不过没有深入完整的学习过,借此机会来学习一下,顺便翻译几篇block相关的文章,本文是第一篇,算是block的入门。本文的最后延伸阅读给出了4篇相关文章,不出意外的话,本周大家能看到对应的中文版。

    目录:

    • Block简介
    • Block的创建
    • 不带参数的Block
    • Block的闭包性(closure)
    • 修改非局部变量
    • Block作为函数的参数
    • 定义Block类型
    • 总结
    • 延伸阅读

    正文

    Block简介

    我们可以把Block当做Objective-C的匿名函数。Block允许开发者在两个对象之间将任意的语句当做数据进行传递,往往这要比引用定义在别处的函数直观。另外,block的实现具有封闭性(closure),而又能够很容易获取上下文的相关状态信息。

    Block的创建

    实际上,block使用了与函数相同的机制:可以像声明函数一样,来声明一个bock变量;可以利用定义一个函数的方法来定义一个block;也可以将block当做一个函数来调用。

    1. // main.m
    2. #import <Foundation/Foundation.h>
    3.  
    4. int main(int argc, const char * argv[]) {
    5. @autoreleasepool {
    6. // Declare the block variable
    7. double (^distanceFromRateAndTime)(double rate, double time);
    8.  
    9. // Create and assign the block
    10. distanceFromRateAndTime = ^double(double rate, double time) {
    11. return rate * time;
    12. };
    13. // Call the block
    14. double dx = distanceFromRateAndTime(35, 1.5);
    15.  
    16. NSLog(@"A car driving 35 mph will travel "
    17. @"%.2f miles in 1.5 hours.", dx);
    18. }
    19. return 0;
    20. }

    在上面的代码中,利用插入符(^)将distanceFromRateAndTime变量标记为一个block。就像声明函数一样,需要包含返回值的类型,以及参数的类型,这样编译器才能安全的进行强制类型转换。插入符(^)跟指针(例如 int *aPointer)前面的星号(*)类似——只是在声明的时候需要使用,之后用法跟普通的变量一样。

    block的定义本质上跟函数一样——只不过不需要函数名。block以签名字符串开始:^double(double rate, double time)标示返回一个double,以及接收两个同样为double的参数(如果不需要返回值,可以忽略掉)。在签名后面是一个大括弧({}),在这个括弧里面可以编写任意的语句代码,这跟普通的函数一样。

    当把block赋值给distanceFromRateAndTime后,我们就可以像调用函数一样调用这个变量了。

    不带参数的Block

    如果block不需要任何的参数,那么可以忽略掉参数列表。另外,在定义block的时候,返回值的类型也是可选的,所以这样情况下,block可以简写为^ { … }:

    1. double (^randomPercent)(void) = ^ {
    2. return (double)arc4random() / 4294967295;
    3. };
    4. NSLog(@"Gas tank is %.1f%% full",
    5. randomPercent() * 100);

    在上面的代码中,利用内置的arc4random()方法返回一个32位的整型随机数——为了获得0-1之间的一个值,通过除以arc4random()方法能够获取到的最大值(4294967295)。

    到现在为止,block看起来可能有点像利用一种复杂的方式来定义一个方法。事实上,block是被设计为闭包的(closure)——这就提供了一种新的、令人兴奋的编程方式。

    Block的闭包性(closure)

    在block内部,可以像普通函数一样访问数据:局部变量、传递给block的参数,全局变量/函数。并且由于block具有闭包性,所以还能访问非局部变量(non-local variable)。非局部变量定义在block之外,但是在block内部有它的作用域。例如,getFullCarName可以使用定义在block前面的make变量:

    1. NSString *make = @"Honda";
    2. NSString *(^getFullCarName)(NSString *) = ^(NSString *model) {
    3. return [make stringByAppendingFormat:@" %@", model];
    4. };
    5. NSLog(@"%@", getFullCarName(@"Accord")); // Honda Accord

    非局部变量会以const变量被拷贝并存储到block中,也就是说block对其是只读的。如果尝试在block内部给make变量赋值,会抛出编译器错误。

    const-non-local-variables

    以const拷贝的方式访问非局部变量

     

    以const拷贝的方式访问非局部变量,意味着block实际上并不是真正的访问了非局部变量——只不过在block中创建了非局部变量的一个快照。当定义block时,无论非局部变量的值是什么,都将被冻结,并且block会一直使用这个值,即使在之后的代码中修改了非局部变量的值。下面通过代码来看看,在创建好block之后,修改make变量的值,会发生什么:

    1. NSString *make = @"Honda";
    2. NSString *(^getFullCarName)(NSString *) = ^(NSString *model) {
    3. return [make stringByAppendingFormat:@" %@", model];
    4. };
    5. NSLog(@"%@", getFullCarName(@"Accord")); // Honda Accord
    6.  
    7. // Try changing the non-local variable (it won't change the block)
    8. make = @"Porsche";
    9. NSLog(@"%@", getFullCarName(@"911 Turbo")); // Honda 911 Turbo

    block的闭包性为block与上下文交互的时候带来极大的便利性,当block需要额外的数据时,可以避免使用参数——只需要简单的使用非局部变量即可。

    修改非局部变量

    冻结中的非局部变量是一个常量值,这也是一种默认的安全行为——因为这可以防止在block中的代码对非局部变量做了意外的修改。那么如果我们希望在block中对非局部变量值进行修改要如何做呢——用__block存储修饰符(storage modifier)来声明非局部变量:

    1. __block NSString *make = @"Honda";

    这将告诉block对非局部变量做引用处理,在block外部make变量和内部的make变量创建一个直接的链接(direct link)。现在就可以在block外部修改make,然后反应到block内部,反过来,也是一样。

    mutable-non-local-variables

    通过引用的方式访问非局部变量

    这跟普通函数中的静态局部变量(static local variable)类似,用__block修饰符声明的变量可以记录着block多次调用的结果。例如下面的代码创建了一个block,在block中对i进行累加。

    1. __block int i = 0;
    2. int (^count)(void) = ^ {
    3. i += 1;
    4. return i;
    5. };
    6. NSLog(@"%d", count()); // 1
    7. NSLog(@"%d", count()); // 2
    8. NSLog(@"%d", count()); // 3

    Block作为函数的参数

    把block存储在变量中有时候非常有用,比如将其用作函数的参数。这可以解决类似函数指针能解决的问题,不过我们也可以定义内联的block,这样代码更加易读。
    例如下面Car interface中声明了一个方法,该方法用来计算汽车的里程数。这里并没有强制要求调用者给该方法传递一个常量速度,相反可以改方法接收一个block——该block根据具体的时间来定义汽车的速度。

    1. // Car.h
    2. #import <Foundation/Foundation.h>
    3.  
    4. @interface Car : NSObject
    5.  
    6. @property double odometer;
    7.  
    8. - (void)driveForDuration:(double)duration
    9. withVariableSpeed:(double (^)(double time))speedFunction
    10. steps:(int)numSteps;
    11.  
    12. @end

    上面代码中block的数据类型是double (^)(double time),也就是说block的调用者需要传递一个double类型的参数,并且该block的返回值为double类型。注意:上面代码中的语法基本与本文开头介绍的block变量声明相同,只不过没有变量名字。
    在函数的实现里面可以通过speedFunction来调用block。下面的示例通过算法计算出汽车行驶的大约距离。其中steps参数是由调用者确定的一个准确值。

    1. // Car.m
    2. #import "Car.h"
    3.  
    4. @implementation Car
    5.  
    6. @synthesize odometer = _odometer;
    7.  
    8. - (void)driveForDuration:(double)duration
    9. withVariableSpeed:(double (^)(double time))speedFunction
    10. steps:(int)numSteps {
    11. double dt = duration / numSteps;
    12. for (int i=1; i<=numSteps; i++) {
    13. _odometer += speedFunction(i*dt) * dt;
    14. }
    15. }
    16.  
    17. @end

    在下面的代码中,有一个main函数,在main函数中block定义在另一个函数的调用过程中。虽然理解其中的语法需要话几秒钟时间,不过这比起另外声明一个函数,再定义withVariableSpeed参数要更加直观。

    1. // main.m
    2. #import <Foundation/Foundation.h>
    3. #import "Car.h"
    4.  
    5. int main(int argc, const char * argv[]) {
    6. @autoreleasepool {
    7. Car *theCar = [[Car alloc] init];
    8.  
    9. // Drive for awhile with constant speed of 5.0 m/s
    10. [theCar driveForDuration:10.0
    11. withVariableSpeed:^(double time) {
    12. return 5.0;
    13. } steps:100];
    14. NSLog(@"The car has now driven %.2f meters", theCar.odometer);
    15.  
    16. // Start accelerating at a rate of 1.0 m/s^2
    17. [theCar driveForDuration:10.0
    18. withVariableSpeed:^(double time) {
    19. return time + 5.0;
    20. } steps:100];
    21. NSLog(@"The car has now driven %.2f meters", theCar.odometer);
    22. }
    23. return 0;
    24. }

    上面利用一个简单的示例演示了block的通用性。在iOS的SDK中有许多API都利用了block的其它一些功能。NSArray的sortedArrayUsingComparator:方法可以使用一个block对元素进行排序,而UIView的animateWithDuration:animations:方法使用了一个block来定义动画的最终状态。此外,block在并发编程中具有强大的作用。

    定义Block类型

    由于block数据类型的语法会很快把函数的声明搞得难以阅读,所以经常使用typedef对block的签名(signature)做处理。例如,下面的代码创建了一个叫做SpeedFunction的新类型,这样我们就可以对withVariableSpeed参数使用一个更加有语义的数据类型。

    1. // Car.h
    2. #import <Foundation/Foundation.h>
    3.  
    4. // Define a new type for the block
    5. typedef double (^SpeedFunction)(double);
    6.  
    7. @interface Car : NSObject
    8.  
    9. @property double odometer;
    10.  
    11. - (void)driveForDuration:(double)duration
    12. withVariableSpeed:(SpeedFunction)speedFunction
    13. steps:(int)numSteps;
    14.  
    15. @end

    许多标准的Objective-C框架也使用了这样的技巧,例如NSComparator

    总结

    Block不仅提供了C函数同样的功能,而且block看起来更加直观。block可以定义为内联(inline),这样在函数内部调用的时候就非常方便,由于block具有闭包性(closure),所以block可以很容易获得上下文信息,而又不会对这些数据产生负面影响。

    延伸阅读

     

    本文由破船翻译●转载请注明出处●2013-07-0

    展开全文
  • IndentationError: expected an indented block解决方案

    万次阅读 多人点赞 2018-07-05 12:32:09
    IndentationError: expected an indented block 翻译过来就是: 缩进错误: 期望一个缩进的块 贴下报错的代码的截图便于观察分析: 好了,直接开始单刀直入解决这个问题,解决方案,在报错的逻辑代码的前面加个...

    自学python,第一次遇到python的运行异常,竟然是这个鬼:
    异常一:

    IndentationError: expected an indented block

    把这段英文报错翻译过来就是: 缩进错误: 期望一个缩进的块
    贴下报错的代码的截图便于观察分析:
    这里写图片描述

    好了,直接开始单刀直入解决这个问题,解决方案,在报错的逻辑代码的前面加个空格就一切ok了,一个缩进就解决了这个异常,解决这个bug不是主要目的,了解python的语法结构和特点才是我们该做的事情。
    1.不像其他语言(C++, java 等等),就拿java举个例子:我们都知道在java里面方法后面是用{}来区分是否属于一个方法的,但在python里面方法体并不使用{}来区分,python的是用缩进来识别语法逻辑块的(i.e. if, while, for, def 等)。同一个if逻辑块下面的语句必须要有相同的缩进,否则python解析器怎么知道if块控制哪些语句?对吧,在python中,所有的逻辑代码块也就是一个方法中的代码,都必须使用相同的缩进来标识区分是同一个方法,否则编译会报错。贴个图解释下:
    这里写图片描述
    2、所谓缩进,就是每一行开头的空白。这个空白可以由多个空格或者制表符组成。python下面你怎么缩进都可以,比如3个空格,2个tab,这样都是合法的。但是同一个逻辑块下面必须用一样的。这一点在上面的图片和文字中已经做过解释和说明。

    异常二:
    安装后在代码编辑区不能写代码,如下图:
    这里写图片描述
    不管怎么做那个白色的块儿都在,不能进行编辑输入代码,后来百度后发现已经有人给出了解决方案,很简单,是因为PyCharm安装了Vim插件 你可以在tools Vim emulator将对勾去掉就可以了,尝试后确实是这样的,在PyCharm中点击Tools然后在弹出的列表中,去掉Vim emulator的对勾就可以正常编辑了。

    以上是本人的一点总结,以后有新的经验或者这方面的认知升级后,会重新完善该篇内容,如果有不对的地方欢迎留言指正改进,感激不尽!

    展开全文
  • CSS的inline、block与inline-block

    万次阅读 2021-03-26 09:48:43
    CSS的inline、block与inline-block 推荐一篇文章,说的很清楚 https://segmentfault.com/a/1190000015202771

    CSS的inline、block与inline-block

    推荐一篇文章,说的很清楚

    https://segmentfault.com/a/1190000015202771

    展开全文
  • block 的妙用:结合block和方法的优点实现iOS的链式编程 -【 完整pod 仓库源码GitHub】 主要针对段落样式NSMutableParagraphStyle和富文本NSMutableAttributedString进行封装 代码效果 xx.kn_addString(@"封装富...

    前言

    【封装富文本API,采用block实现链式编程】(block 的妙用:结合block和方法的优点实现iOS的链式编程)

    1、原理文章:https://kunnan.blog.csdn.net/article/details/107835195
    block 的妙用:结合block和方法的优点实现iOS的链式编程
    2、功能:主要针对段落样式NSMutableParagraphStyle和富文本NSMutableAttributedString进行封装,提升开发效率
    3、下载地址:https://download.csdn.net/download/u011018979/14038715
    4、实现步骤:方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值)
    5、链式编程特点:将多个操作(多行代码)通过点号(.)链接在一起成为一句代码,使代码可读性好a(1).b(2).c(3)。

        xx.kn_addString(@"封装富文本API").kn_fontColor(UIColor.redColor).kn_addString(@"采用block实现链式编程").kn_fontColor(UIColor.blueColor).kn_addString(@"!");
    
    

    在这里插入图片描述
    在这里插入图片描述

    I、封装富文本API,采用block实现链式编程的核心思想

    1.1 关键步骤

    • 声明block属性
    k_PropertyStatement(strong, NSMutableAttributedString, NSString*, kn_addString)// 好处是Xcode的提示比较友好
    //- (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString// 不推荐直接声明getter方法,推荐上面的声明的block属性
    
    
    • 实现getter方法
    - (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString{
        return ^id(NSString *str){
            NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc]initWithString:str];
            self.leftStr = str;
            [self appendAttributedString:attStr];
            return self;
        };
    }
    
    

    1.2 使用方法

    • Installation
    pod 'ChainAttributedString'
    
    
    • 声明
    //#import <ChainAttributedString/ChainAttributedString-umbrella.h>
    
    #import <ChainAttributedString/NSMutableAttributedString+Chain.h>
    
    
    • demo
    
    
        UILabel *x = [UILabel new];
        x.textAlignment = NSTextAlignmentCenter;
        
        [self.view addSubview:x];
        
        x.frame = self.view.frame;
        
        
        x.numberOfLines = 0;
        
        NSMutableAttributedString *xx  = [[NSMutableAttributedString alloc]init];
        
        
        xx.kn_addString(@"封装富文本API").kn_fontColor(UIColor.redColor).kn_addString(@"采用block实现链式编程").kn_fontColor(UIColor.blueColor).kn_addString(@"!");
        
        
        
        
        
        x.attributedText =xx;
        
    

    II、实现细节

    2.1 使用宏进行block属性的声明

    #define k_PropertyStatement(propertyModifier,className, propertyPointerType, propertyName) \
    @property (nonatomic, propertyModifier) className *(^propertyName)(propertyPointerType);
    
    
    - (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString; 直接声明方法也行
    #define k_methodStatement(returnClassName,paramPointerType, methodName) \
    - (returnClassName * _Nonnull (^)(paramPointerType * _Nonnull))methodName;
    
    

    2.2 代码

    完整pod 仓库源码GitHub(私有Private)

    • NSMutableAttributedString+Chain.h
    
    // block 的妙用:结合block和方法的优点实现iOS的链式编程
    //其他更多链式编程的例子:https://github.com/zhangkn/DKUsingblockImplementChainProgramming
    /**
     核心思想
     */
    //核心的实现步骤:方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值)
    //链式编程特点:将多个操作(多行代码)通过点号(.)链接在一起成为一句代码,使代码可读性好a(1).b(2).c(3)。
    
    
    //##------ 实现链式编程的两种形式:本质都是一样的,就是执行(getter)方法之后,得到一个block,block必须有返回值(本身对象),block参数(需要操作的值)
    //1、声明方法: 缺点就是 Xcode提示不太友好。不推荐 声明方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值)
    //p.run() <=> [p run]();//执行方法的同时之后,立即执行方法返回的block
    
    //2、声明属性: 本质就是利用他的getter方法
    //声明属性,属性的类型是block,block必须有返回值(本身对象),block参数(需要操作的值)
    
    
    //---------##
    
    
    
    
    
    
    
    
    
    
    #import "kConst.h"
    
    
    
    #import <Foundation/Foundation.h>
    /**
     用于动态新增属性
     */
    #import <objc/runtime.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    /*
    // NSUnderlineStyleNone 不设置下划线/删除线
    // NSUnderlineStyleSingle 设置下划线/删除线为细的单线
    // NSUnderlineStyleThick 设置下划线/删除线为粗的单线
    // NSUnderlineStyleDouble 设置下划线/删除线为细的双线
    
    // NSUnderlinePatternSolid 设置下划线/删除线样式为连续的实线
    // NSUnderlinePatternDot 设置下划线/删除线样式为点,也就是虚线,比如这样:------
    // NSUnderlinePatterDash 设置下划线/删除线样式为破折号,比如这样:—— —— ——
    // NSUnderlinePatternDashDot 设置下划线/删除线样式为连续的破折号和点,比如这样:——-——-——-
    // NSUnderlinePatternDashDotDot 设置下划线/删除线样式为连续的破折号、点、点,比如:——--——--——--
    
    // NSUnderlineByWord 在有空格的地方不设置下划线/删除线
    */
    static const char leftMutableAttributedStringKey;
    
    @interface NSMutableAttributedString (Chain)
    /**
     记录最近一次新添加的富文本对应的字符串,以便进行后续的其他操作
     */
    @property (strong, nonatomic) NSString *leftStr;
    
    
    //每次kn_addString就是一句新的富文本
    //kn_addString方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值)
    //富文本的block属性,发返回值就是自己,block的参数类型propertyPointerType
    
    //k_PropertyStatement(strong, NSMutableAttributedString, NSString*, kn_addString)
    
    
    k_PropertyStatement(strong, NSMutableAttributedString, NSString*, kn_addString)
    //- (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString; 直接声明方法也行
    
    
    // 字体颜色
    k_PropertyStatement(strong, NSMutableAttributedString, UIColor*, kn_fontColor)
    // 字体大小
    k_PropertyStatement(strong, NSMutableAttributedString, UIFont*, kn_fontSize);
    // 字体背景颜色
    k_PropertyStatement(strong, NSMutableAttributedString, UIColor*, kn_fontBgColor);
    // 字体间距
    k_PropertyStatement(assign, NSMutableAttributedString, NSInteger, kn_fontSpacing);
    // 删除线
    k_PropertyStatement(assign, NSMutableAttributedString, NSUnderlineStyle, kn_strikethrough);
    // 删除线颜色
    k_PropertyStatement(strong, NSMutableAttributedString, UIColor*, kn_strikethroughColor);
    // 下划线
    k_PropertyStatement(assign, NSMutableAttributedString, NSUnderlineStyle, kn_underline);
    // 下划线颜色
    k_PropertyStatement(strong, NSMutableAttributedString, UIColor*, kn_underlineColor);
    // 笔画宽度 正值中空 负值填充
    k_PropertyStatement(assign, NSMutableAttributedString, NSInteger, kn_strokeWidth);
    // 笔画颜色
    k_PropertyStatement(strong, NSMutableAttributedString, UIColor*, kn_strokeColor);
    // 倾斜 正值右倾,负值左倾
    k_PropertyStatement(assign, NSMutableAttributedString, CGFloat, kn_obliqueness);
    // 书写方向
    //@(NSWritingDirectionRightToLeft|NSWritingDirectionOverride)倒着写
    k_PropertyStatement(strong, NSMutableAttributedString, NSArray*, kn_direction);
    // 跳转URL
    k_PropertyStatement(strong, NSMutableAttributedString, NSString*, kn_link);
    // 图文混排等
    k_PropertyStatement(strong, NSMutableAttributedString, NSTextAttachment*, kn_attachment);
    // 段落属性
    k_PropertyStatement(strong, NSMutableAttributedString, NSMutableParagraphStyle*, kn_paragraph);
    
    
    
    
    
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    • NSMutableAttributedString+Chain.m
    //
    //  NSMutableAttributedString+Chain.m
    //  ChainAttributedString
    //
    //  Created by mac on 2020/8/6.
    //
    
    #import "NSMutableAttributedString+Chain.h"
    
    
    
    @implementation NSMutableAttributedString (Chain)
    
    - (void)setLeftStr:(NSString *)leftStr{
        objc_setAssociatedObject(self, &leftMutableAttributedStringKey, leftStr, OBJC_ASSOCIATION_COPY);
    }
    
    - (NSString *)leftStr{
       return objc_getAssociatedObject(self, &leftMutableAttributedStringKey);
    }
    
    - (void)setKn_addString:(NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString{
        
    }
    
    - (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_addString{
        return ^id(NSString *str){
            NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc]initWithString:str];
            self.leftStr = str;
            [self appendAttributedString:attStr];
            return self;
        };
    }
    
    - (void)setKn_fontColor:(NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_fontColor{}
    
    - (NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_fontColor{
        return ^id(UIColor *color){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    
    
    - (void)setKn_fontSize:(NSMutableAttributedString * _Nonnull (^)(UIFont * _Nonnull))kn_fontSize{};
    
    - (NSMutableAttributedString * _Nonnull (^)(UIFont * _Nonnull))kn_fontSize{
        return ^id(UIFont *size) {
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSFontAttributeName value:size range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSFontAttributeName value:size range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    
    
    
    - (void)setKn_fontBgColor:(NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_fontBgColor{};
    - (NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_fontBgColor{
        return ^id(UIColor *bgColor){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSBackgroundColorAttributeName value:bgColor range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSBackgroundColorAttributeName value:bgColor range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    
    
    - (void)setKn_fontSpacing:(NSMutableAttributedString * _Nonnull (^)(NSInteger))kn_fontSpacing{};
    
    
    - (NSMutableAttributedString * _Nonnull (^)(NSInteger))kn_fontSpacing{
        return ^id(NSInteger spacing){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSKernAttributeName value:@(spacing) range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSKernAttributeName value:@(spacing) range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    
    
    - (void)setKn_strikethrough:(NSMutableAttributedString * _Nonnull (^)(NSUnderlineStyle))kn_strikethrough{};
    
    
    - (NSMutableAttributedString * _Nonnull (^)(NSUnderlineStyle))kn_strikethrough{
        return ^id(NSUnderlineStyle style){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSStrikethroughStyleAttributeName value:@(style) range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSStrikethroughStyleAttributeName value:@(style) range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    
    
    - (void)setKn_strikethroughColor:(NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_strikethroughColor{};
    
    - (NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_strikethroughColor{
        return ^id(UIColor *color){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSStrikethroughColorAttributeName value:color range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSStrikethroughColorAttributeName value:color range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    
    
    - (void)setKn_underline:(NSMutableAttributedString * _Nonnull (^)(NSUnderlineStyle))kn_underline{};
    
    - (NSMutableAttributedString * _Nonnull (^)(NSUnderlineStyle))kn_underline{
        return ^id(NSUnderlineStyle style){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSUnderlineStyleAttributeName value:@(style) range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSUnderlineStyleAttributeName value:@(style) range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    - (void)setKn_underlineColor:(NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_underlineColor{};
    
    - (NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_underlineColor{
        return ^id(UIColor *color){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSUnderlineColorAttributeName value:color range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSUnderlineColorAttributeName value:color range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    - (void)setKn_strokeWidth:(NSMutableAttributedString * _Nonnull (^)(NSInteger))kn_strokeWidth{};
    
    - (NSMutableAttributedString * _Nonnull (^)(NSInteger))kn_strokeWidth{
        return ^id(NSInteger width){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSStrokeWidthAttributeName value:@(width) range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSStrokeWidthAttributeName value:@(width) range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    - (void)setKn_strokeColor:(NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_strokeColor{};
    
    - (NSMutableAttributedString * _Nonnull (^)(UIColor * _Nonnull))kn_strokeColor{
        return ^id(UIColor *color){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSStrokeColorAttributeName value:color range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSStrokeColorAttributeName value:color range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    - (void)setKn_obliqueness:(NSMutableAttributedString * _Nonnull (^)(CGFloat))kn_obliqueness{};
    
    - (NSMutableAttributedString * _Nonnull (^)(CGFloat))kn_obliqueness{
        return ^id(CGFloat obliqueness){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSObliquenessAttributeName value:@(obliqueness) range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSObliquenessAttributeName value:@(obliqueness) range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    - (void)setKn_direction:(NSMutableAttributedString * _Nonnull (^)(NSArray * _Nonnull))kn_direction{};
    
    - (NSMutableAttributedString * _Nonnull (^)(NSArray * _Nonnull))kn_direction{
        return ^id(NSArray *direction){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSWritingDirectionAttributeName value:direction range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSWritingDirectionAttributeName value:direction range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    - (void)setKn_link:(NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_link{};
    
    - (NSMutableAttributedString * _Nonnull (^)(NSString * _Nonnull))kn_link{
        return ^id(NSString *link){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSLinkAttributeName value:[NSURL URLWithString:link] range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSLinkAttributeName value:[NSURL URLWithString:link] range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    
    - (void)setKn_attachment:(NSMutableAttributedString * _Nonnull (^)(NSTextAttachment * _Nonnull))kn_attachment{}
    
    
    - (NSMutableAttributedString * _Nonnull (^)(NSTextAttachment * _Nonnull))kn_attachment{
        return ^id(NSTextAttachment *attachment){
            NSAttributedString * imageStr = [NSAttributedString attributedStringWithAttachment:attachment];
            [self appendAttributedString:imageStr];
            return self;
        };
    }
    
    - (void)setKn_paragraph:(NSMutableAttributedString * _Nonnull (^)(NSMutableParagraphStyle * _Nonnull))kn_paragraph{};
    - (NSMutableAttributedString * _Nonnull (^)(NSMutableParagraphStyle * _Nonnull))kn_paragraph{
        return ^id(NSMutableParagraphStyle *paragraph){
            if ([self.leftStr isEqualToString:@""]) {
                [self addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(0, self.length)];
            }else{
                [self addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(self.length-self.leftStr.length, self.leftStr.length)];
            }
            return self;
        };
    }
    
    
    
    
    @end
    
    

    III、案例

    3.1 自定义相机

    在这里插入图片描述

    #import <ChainAttributedString/NSMutableAttributedString+Chain.h>
    
    
            NSMutableAttributedString *xx  = [[NSMutableAttributedString alloc]init];
            
            xx.kn_addString(@"请调整好光线,将身份证").kn_fontColor(rgb(255,255,255)).kn_addString(@"人像面").kn_fontColor(rgb(225,66,66)).kn_addString(@"移入框内").kn_fontColor(rgb(255,255,255));
    
            
            
            
            
            
            _tishiLabel.attributedText = xx;
    
    
    • 旋转90度
            _tishiLabel.transform = CGAffineTransformMakeRotation(M_PI/2);
    
            
            [self.view addSubview:_tishiLabel];
    
            
            __weak __typeof__(self) weakSelf = self;
            
    
            [_tishiLabel mas_makeConstraints:^(MASConstraintMaker *make) {
                
                
                make.centerX.equalTo(weakSelf.view.mas_right).offset(kAdjustRatio(- 23));
    
                
                
                make.centerY.offset(kAdjustRatio(0));
    
                        
            }];
    
    

    在这里插入图片描述

    3.2 展示信用卡标签

    https://kunnan.blog.csdn.net/article/details/117733632

    在这里插入图片描述

    创建带有图片的富文本

    @interface NSAttributedString (NSAttributedStringAttachmentConveniences)
    // A convenience method for creating an attributed string containing attachment using NSAttachmentCharacter as the base character.
    + (NSAttributedString *)attributedStringWithAttachment:(NSTextAttachment *)attachment API_AVAILABLE(macos(10.0), ios(7.0));
    @end
    
    
    
    

    see also

    https://kunnan.blog.csdn.net/article/details/75219317

    • 实现删除线
    
    /**
     使用NSAttributedString 实现删除线
     @param lab
     */
    - (void)setupNSStrikethroughColorAttributeName:(UILabel*)lab{
        
        NSString* oldPrice = lab.text;
        
        NSUInteger length = [oldPrice length];
        
        NSMutableAttributedString *attri = [[NSMutableAttributedString alloc] initWithString:oldPrice];
        
        [attri addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlinePatternSolid | NSUnderlineStyleSingle) range:NSMakeRange(0, length)];
    //    [attri addAttribute:NSStrikethroughColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, length)];
        [lab setAttributedText:attri];
        
    }
    
    
    展开全文
  • block、inline和inline-block

    千次阅读 2019-01-07 21:49:53
    block、inline、inline-block行内元素和块级元素blockinlineinline-block行内元素和块级元素的区别常见用法 行内元素:又叫内联元素, 块级元素:是一个元素,占用了全部宽度,在前后都是换行符
  • iOS block之三种block

    千次阅读 2017-09-10 18:04:02
    本篇博文主要根据block在内存中存在的位置介绍block的种类以及其生命周期等特性
  • 表头标题 Another Block Title Badge数字 f7-badge color="red">5f7-badge> block   block inner   Block Title block   block inset
  • Block Site

    千次阅读 2017-09-04 01:06:58
    Block Site出于各种各样的原因,有时我们需要屏蔽一些网站。 本文提供 3 种途径来实现这个功能。1 Google Chrome 插件 blocksitehttps://chrome.google....
  • HBase BlockCache系列第一篇文章《走进BlockCache》从全局视角对HBase中缓存、Memstore等作了简要概述,并重点介绍了几种BlockCache方案及其演进过程,对此还不了解的可以点这里。本文在上文的基础上深入BlockCache...
  • resnet block

    千次阅读 2019-06-03 14:50:55
    Sequential( (0): ResidualBlock( (left): Sequential( (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True...
  • BlockManager

    千次阅读 2016-09-22 06:47:43
    Spark为了避免Hadoop读写磁盘的I/O...1. 块管理器BlockManager块管理器BlockManager是Spark存储体系中的核心组件。Driver 和 Executor都会创建BlockManager。其主构造器如下:/** * Manager running on every node (d
  • Dropblock

    千次阅读 2018-11-07 10:10:00
    昨天arXiv新上一篇被NIPS2018会议接收的论文《DropBlock: A regularization method for convolutional networks》,作者为来自谷歌大脑的研究人员,提出了一种专门针对卷积层正则化的方法,方法非常简单,有效改进了...
  • 正则化方法之DropBlock

    万次阅读 多人点赞 2018-12-19 18:06:06
    DropBlock: A regularization method for convolutional networks  Github: https://github.com/miguelvr/dropblock https://github.com/DHZS/tf-dropblock   论文主要提出了一种针对卷积层的正则化方法...
  • iOS Block面试题(Block的几种形式)

    千次阅读 2019-11-07 10:38:24
    Block的几种形式 分为全局Block(_NSConcreteGlobalBlock)、栈Block(_NSConcreteStackBlock)、堆Block(_NSConcreteMallocBlock)三种形式 其中栈Block存储在栈(stack)区,堆Block存储在堆(heap)区,全局Block存储在...
  • block、inline、inline-block的区别

    千次阅读 2019-01-15 21:14:58
    一、display:block特点 1、独占一行,多个block元素另起一行,默认情况下,block元素宽度自动填满其父元素宽度 2、block元素可以设置width,height属性。块元素即使设置了宽度,仍然是独占一行。 3、block元素可以设置...
  • display: inline、block和inline-block

    万次阅读 多人点赞 2018-08-16 17:16:54
    inline:使元素变成行内元素(内联),拥有行内元素的特性,即 1. 与其他行内元素共享一行 2. 不能修改width、...block:使元素变成块级元素,拥有块级的特性,即 1.独占一行,在不设置自己的宽度的情况下,...
  •  1.block:文件系统中存储数据的最小单元,ext3文件系统中,创建时默认4k,分为存储文件数据的data block和存储目录数据的directory block  2.inode:又称“索引节点”,每一个inode对应一个文件或目录,记录了...
  • block传值

    千次阅读 2014-07-19 17:37:47
    block传值 block传值. //流程: 1.后一个界面定义一个block,并且定义一个属性block 2.在后一个界面返回前一个界面的瞬间,(即:创建完成一个界面之后),调用block; 3.前一个界面实现block的实现 4.后一个界面在合适的...
  • Block 专题

    千次阅读 2015-09-07 17:38:23
    Objective-C中的Block http://www.cocoachina.com/ios/20150109/10891.html 深度围观block:第一集&第二集 http://www.cocoachina.com/ios/20130712/6584.html 深度围观block:第三集 ...
  • Block详解

    千次阅读 2014-09-16 21:34:01
    Block简介 我们可以把Block当做Objective-C的匿名函数。Block允许开发者在两个对象之间将任意的语句当做数据进行传递,往往这要比引用定义在别处的函数直观。另外,block的实现具有封闭性(closure),而又能够很容易...
  • 什么是BlockBlock是ios中一种比较特殊的数据类型,是苹果官方特别推荐使用的一种数据类型,应用场景有:动画、多线程、集合遍历、网络请求回调等 Block的作用:用来保存某一段代码,可以在恰当的时间取出来再...
  • html中的block,inline,inline-block

    千次阅读 2018-11-01 17:34:42
    display:block 1.block元素会独占一行,多个block元素会各自新起一行。默认情况下,block元素宽度自动填满其父元素宽度。 2.block元素可以设置width,height属性。块级元素即使设置了宽度,仍然是独占一行。 3....
  • Block 4:Block实质解析

    千次阅读 2014-04-16 23:30:39
    Block是“带有局部变量值的匿名函数”,但Block究竟是什么呢?  前面所说的Block语法看上去好像很特别,但它实际上是作为极普通的C语言源代码来处理的。通过支持Block的编译器,含有Block语句的源代码转换为一般...
  • ios block

    千次阅读 2013-09-04 15:28:26
    一、block内局部变量无法修改,但为什么可以添加数组? NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"a",@"b",@"abc",nil]; NSMutableArray *mArrayCount = [NSMutableArray arrayWithCapacity:1]...
  • data block address

    千次阅读 2016-06-23 20:01:43
    这里讨论的不是数据库管理员DBA,而是数据块地址DBA:Data Block Address! A Data Block Address (DBA) is the address of an Oracle data block for access purposes. ----源自《Oracle内核技术揭秘》的探索 DBA的...
  • Block对象

    千次阅读 2013-08-20 17:12:26
    今天总结学习一下Block。 1、声明Block对象变量  声明包括变量名和类型两个属性。如下代码:  int (^addr)(inta,int b);  这行代码声明了一个名为adder的Block变量,其指向的是Block对象应该有两个int实参,...
  • Block用法解析

    万次阅读 2016-05-01 17:15:58
    Block代码块是对C做出的一个补充,初次体验代码块,无比的不适应。古怪的语法确实让人不易入门甚至精通。但若能够深入精通Block的使用,会给代码带来层次上的提升。Block就是一段在将来被执行的代码 定义块语法 ^[块...
  • __block变量生成的会跟着Block从栈上复制到堆上,例如有两个Block使用了这个__block变量,一开始和Block一 样是初始化在栈上的,但是当有个Block复制到堆上的时候时,__block也跟着被复制,当剩下的Block也一并被...
  • block,inline和inline-block概念和区别

    千次阅读 2015-07-29 16:35:07
    block和inline这两个概念是简略的说法,完整确切的说应该是 block-level elements (块级元素) 和 inline elements (内联元素)。block元素通常被现实为独立的一块,会单独换一行;inline元素则前后不会产生换行,一...
  • iOS Block的基本使用以及Block传值

    千次阅读 2016-04-14 15:52:02
    block为我们提供了一个非常便捷的方法去实现各种传值以及回调 合理的使用block可以减少代码量以及更加优雅的实现功能 现做个小整理如下: #pragma mark About Block //block的原型: NSString *(^myBlock)(int)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 282,302
精华内容 112,920
关键字:

block