ios专题 -block用法

时间:2022-12-31 18:42:43
  • what is block

Blocks are a language-level feature added to C, Objective-C and C++, which allow you to create distinct segments of code that can be passed around to methods or functions as if they were values. Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDictionary. They also have the ability to capture values from the enclosing scope, making them similar to closures or lambdas in other programming languages。

块是一个语言级功能添加到C,Objective-C和C + +中,这允许你创建的代码的不同部分可以被传递到方法或函数,如果他们的值。块是Objective-C的对象,这意味着它们可以被添加到像的 NSArray或NSDictionary的集合。他们还必须从封闭范围捕捉值,使它们类似于其他编程语言倒闭或lambda表达式的能力。

  • block function

A block is an anonymous inline collection of code that:

块是一个匿名代码内嵌集合

  1.Has a typed argument list just like a function。有一个类型参数列表就像一个函数

  2.Has an inferred or declared return type。有一个推断或声明的返回类型

  3.Can capture state from the lexical scope within which it is defined。可以从内部定义它的词法范围捕捉状态

  4.Can optionally modify the state of the lexical scope。可以选择修改的词法作用域的状态

  5.Can share the potential for modification with other blocks defined within the same lexical scope。可以用相同的词法范围内定义的其它块共享进行修改的可能性

  6.Can continue to share and modify state defined within the lexical scope (the stack frame) after the lexical scope (the stack frame) has been destroyed。可以继续  分享和修改词法范围(堆栈帧)中定义的状态后,词法范围(堆栈帧)已被破坏

You can copy a block and even pass it to other threads for deferred execution (or, within its own thread, to a runloop). The compiler and runtime arrange that all variables referenced from the block are preserved for the life of all copies of the block. Although blocks are available to pure C and C++, a block is also always an Objective-C object.

您可以复制块,甚至把它传递给其他线程的延迟执行(或者,在它自己的线程,在runloop)。该编译器和运行安排,从块中引用的所有变量都保存在块的所有副本的使用寿命。虽然块可用于纯C和C + +中,一个块也总是一个Objective-C的对象。

  • define block

Block variables hold references to blocks. You declare them using syntax similar to that you use to declare a pointer to a function, except that you use ^ instead of *. The block type fully interoperates with the rest of the C type system. The following are all valid block variable declarations:

块变量持有引用块。你声明它们使用的语法类似于用于声明一个指向函数的指针,除非你使用^,而不是* 。块类型完全互操作与C型系统的其余部分。以下是所有有效块的变量声明:

oid (^blockReturningVoidWithVoidArgument)(void);
int (^blockReturningIntWithIntAndCharArguments)(int, char);
void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);

blocks also support variadic (...) arguments. A block that takes no arguments must specify void in the argument list.

块还支持可变参数(...)的参数。块,它没有参数必须在参数列表中指定void

Blocks are designed to be fully type safe by giving the compiler a full set of metadata to use to validate use of blocks, parameters passed to blocks, and assignment of the return value. You can cast a block reference to a pointer of arbitrary type and vice versa. You cannot, however, dereference a block reference via the pointer dereference operator (*)—thus a block's size cannot be computed at compile time.

块被设计为完全类型安全的通过给编译器一套完整的元数据的使用,以验证使用的块,传递给块参数和返回值的分配。你可以投一个块引用任意类型的指针,反之亦然。你可以没有,但是,通过解引用指针解引用操作符(*)这样一个块的大小的块参照不能在编译时计算。

You can also create types for blocks—doing so is generally considered to be best practice when you use a block with a given signature in multiple places:

您还可以创建类型为块,这样做通常被认为是最佳实践,当你在多个地方使用与给定的签名块。

typedef float (^MyBlockType)(float, float);
 
MyBlockType myFirstBlock = // ... ;
MyBlockType mySecondBlock = // ... ;
  • Blocks and Variable

Within the block object’s body of code, variables may be treated in five different ways.

You can reference three standard types of variable, just as you would from a function:

  1.Global variables, including static locals。 全局变量, 包括全局静态变量

  2.Global functions (which aren’t technically variables)。全局函数(不是技术上的变量)

  3.Local variables and parameters from an enclosing scope。一个封闭的范围局部变量和参数

Blocks also support two other types of variable:

  1. At function level are __block variables. These are mutable within the block (and the enclosing scope) and are preserved if any referencing block is copied to the heap.在函数级别是__block变量。这是块内可变(和封闭范围),并保留如有引用块被复制到堆

  2. const imports. 引入的const修饰的变量

Finally, within a method implementation, blocks may reference Objective-C instance variables—see “Object and Block Variables.”

The following rules apply to variables used within a block:

  1. Global variables are accessible, including static variables that exist within the enclosing lexical scope.

  2. Parameters passed to the block are accessible (just like parameters to a function).

  3. Stack (non-static) variables local to the enclosing lexical scope are captured as const variables.

    Their values are taken at the point of the block expression within the program. In nested blocks, the value is captured from the nearest enclosing scope.

  4. Variables local to the enclosing lexical scope declared with the __block storage modifier are provided by reference and so are mutable.

    Any changes are reflected in the enclosing lexical scope, including any other blocks defined within the same enclosing lexical scope. These are discussed in more detail in “The __block Storage Type.”

  5. Local variables declared within the lexical scope of the block, which behave exactly like local variables in a function.

    Each invocation of the block provides a new copy of that variable. These variables can in turn be used as const or by-reference variables in blocks enclosed within the block.

  • The __block Storage Type

You can specify that an imported variable be mutable—that is, read-write— by applying the __block storage type modifier. __block storage is similar to, but mutually exclusive of, the register, auto, and static storage types for local variables.

__block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created within the variable’s lexical scope. Thus, the storage will survive the destruction of the stack frame if any copies of the blocks declared within the frame survive beyond the end of the frame (for example, by being enqueued somewhere for later execution). Multiple blocks in a given lexical scope can simultaneously use a shared variable.

As an optimization, block storage starts out on the stack—just like blocks themselves do. If the block is copied using Block_copy (or in Objective-C when the block is sent a copy), variables are copied to the heap. Thus, the address of a __block variable can change over time.

作为一种优化,块存储开出的栈就像块本身做。如果块使用Block_copy(或Objective-C中,当块被发送副本)复制,变量将被复制到堆。因此,__block变量的地址可以随时间而改变

There are two further restrictions on __block variables: they cannot be variable length arrays, and cannot be structures that contain C99 variable-length arrays.

这里是关于__block变量的两个进一步限制:它们不能是可变长度数组;不能包含C99可变长数组结构;

  • using block

  1. 定义局部块,现做现用。 见代码:

2. 使用块做为函数的参数传递。