Date
Jul. 14th, 2024
 
2024年 6月 9日

Post: iOS 入门 014: Block

iOS 入门 014: Block

Published 12:04 Apr 15, 2012.

Created by @ezra. Categorized in #Programming, and tagged as #iOS.

Source format: Markdown

Table of Content

block

定义

inlineBlock

return_value ^(block_name)(arg_list) = return_value ^(arg_list){
    code_block;
}

typedef Block

  • block是一种数据类型,可以定义类型,当作返回值

typedefBlock.m

#import <Foundation/Foundation.h>
typedef void^(myBlock)();
myBlock myDemo(){
    myBlock mb = ^{
        NSLog(@"test");
    }
    return mb;
}
int main(){
    myBlock mb = myDemo();
    mb();
    return 0;
}

循环引用问题

  • block在定义时会默认对外部变量做一次copy(强引用)

  • 在Obj-C中定义指针变量默认都是strong类型,可以使用__weak修饰改为弱引用

  • 如果block中出现self时要加以注意,可能会出现循环引用(并非绝对)

  • 利用dealloc方法可以协助检测循环引用

调用

  • block_name(arg_list)

自定义视图传值:block与代理

实现

  • block

    • 调用方

      • 准备块代码
    • 被调用方

      • 定义代码块属性

      • 需要时执行

  • 代理

    • 代理

      • 遵守协议

      • 设置代理

      • 实现方法

    • 委托

      • 定义协议

      • 定义代理属性

      • 需要时调用代理方法

block与代理的选择

  • block与代理在一些场合时可以互换的

    • block

      • block适合比较小巧的回调,通常1~3回调方法比较合适

      • 如果回调的方法很多时使用block会显得很臃肿,例如UITableView

    • 代理

      • 使用代理可以制定协议方法是否必须实现

block数组排序/遍历

compare方法

  • 可以比较两个对象 (NSNumber, NSString, NSDate....)

compare

- (NSComparisonResult)compare:(NSNumber *)otherNumber;

数组排序

sortedArrayUsingComparator

- (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr NS_AVAILABLE(10_6, 4_0);
typedef NS_ENUM(NSInteger, NSComparisonResult) {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending};
/*
NSOrderedAscending = -1L, 升序
NSOrderedSame,            相同
NSOrderedDescending       降序
*/
#if NS_BLOCKS_AVAILABLE
typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
#endif

数组遍历

  • 所有的参数都已经准备到位,可以直接使用

  • 效率比传统方式快(对比for ( in ){})

enumerate

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);

示例代码

array_block.m

#import <Foundation/Foundation.h>
int main(){
    NSArray* array = @[ @5, @4, @2, @1, @3 ];
    // 数组排序
   NSArray* result = [array sortedArrayUsingComparator:^NSComparisonResult(NSNumber* num1, NSNumber* num2) {
    // 升序
    return [num1 compare:num2];
    }];
   NSLog(@"%@", result);
}

// 数组遍历
void enumerate(NSArray *array){
    [array enumerateObjectsUsingBlock:^(NSNumber* num, NSUInteger idx, BOOL* stop) {
        NSLog(@"%@", num);
        if (idx == 3) { // 遍历到第三个时结束
            *stop = YES;
        }
    }];
}

block常见题目

block-copy

block_copy_release.m

#import <Foundation/Foundation.h>
typedef void^(myBlock)();
myBlock myDemo(){
    int i = 10;
    myBlock mb = ^{
        NSLog(@"i = %d",i);
    }
    //错误解决办法:⏎ [mb copy];
    return Block_copy(mb);
}
int main(){
    myBlock mb = myDemo();
    mb();
    Block_release(mb);
    return 0;
}

重构

  • 新建方法

  • 将代码复制到新方法

  • 调整参数

#import <Foundation/Foundation.h>
void myDay(void (^myWork)()) // 和 inlineBock 的左边一模一样
{
    NSLog(@"起床");
    NSLog(@"出门");
    // 执行block参数,在需要的时候执行
    myWork();
    NSLog(@"下班回家");
    NSLog(@"洗洗睡了");
}

void day1()
{
    // 准备代码,格式和inlineBlock右边一模一样
    myDay(^{
        NSLog(@"新人报道");
    });
}

void day2()
{
    myDay(^{
        NSLog(@"看公司代码");
    });
}

int main(){
    day1();
    day2();
    return 0;
}
Pinned Message
HOTODOGO
I'm looking for a SOFTWARE PROJECT DIRECTOR / SOFTWARE R&D DIRECTOR position in a fresh and dynamic company. I would like to gain the right experience and extend my skills while working in great teams and big projects.
Feel free to contact me.
For more information, please view online résumé or download PDF
本人正在寻求任职 软件项目经理 / 软件技术经理 岗位的机会, 希望加⼊某个新鲜⽽充满活⼒的公司。
如有意向请随时 与我联系
更多信息请 查阅在线简历下载 PDF