The power of a closure is its ability to reference local variables and act upon them while executing in a different activation frame. C API often handles this by allowing a context pointer to be passed in and passed along to a corresponding function and having the custom function treat the opaque context value as a custom structure with appropriate parameterization (see
qsort_r
). This is cumbersome.
In many cases, you don’t need to declare block variables; instead you simply write a block literal inline where it’s required as an argument. The following example uses the
qsort_b
function.qsort_b
is similar to the standardqsort_r
function, but takes a block as its final argument.
都有对qsort_b
和qsort_r
的举例说明,这篇文章是介绍这两个函数的使用方法:
输出char数组:
- (void)_print_char_array:(char **)charArray len:(int)len
{
for (int i = 0; i < len; i++) {
char *tmp = charArray[i];
NSLog(@"%s", tmp);
}
}
qsort_b
的使用
- (void)test_qsort_b
{
char *myCharacters[3] = { "TomJohn", "George", "Charles Condomine" };
NSLog(@"qsort_b before");
[self _print_char_array:myCharacters len:3];
qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) {
char *left = *(char **)l;
char *right = *(char **)r;
return strncmp(left, right, 1);
});
NSLog(@"qsort_b after");
[self _print_char_array:myCharacters len:3];
}
qsort_b
最后一个参数就是Objective-C的block
qsort_r
的使用
typedef struct RXBlockQSortRParam {
int a;
int b;
}RXBlockQSortRParam;
static int _s_compar (void *tmp, const void *l, const void *r) {
RXBlockQSortRParam *param = (RXBlockQSortRParam *)tmp;
param->a = 10;
param->b = 100;
char *left = *(char **)l;
char *right = *(char **)r;
return strncmp(left, right, 1);
}
@implementation RXBlockQSortBRObject
- (void)test_qsort_r
{
char *myCharacters[3] = { "TomJohn", "George", "Charles Condomine" };
RXBlockQSortRParam param = {0, 0};
[self _print_char_array:myCharacters len:3];
NSLog(@"qsort_r before a:%zd, b:%zd", param.a, param.b);
qsort_r(myCharacters, 3, sizeof(char *), ¶m, _s_compar);
[self _print_char_array:myCharacters len:3];
NSLog(@"qsort_r after a:%zd, b:%zd", param.a, param.b);
}
@end
// output
qsort_r before a:0, b:0
qsort_r after a:10, b:100
qsort_b
的第四个参数是额外参数,是一个void *
的指针,在iOS的Framework中有很多这种方式进行参数传递的。
网友评论