swift-oc和swift block和代理

一、闭包或block

1.1、swift 闭包表达式作为参数的形式

Swift 复制代码
一、闭包的定义
func exec(v1: Int, v2: Int, fn: (Int, Int) -> Int) {
print(fn(v1, v2))
}
二、调用
exec(v1: 10, v2: 20, fn: {
(v1: Int, v2: Int) -> Int in
return v1 + v2 })

1.2、swift 闭包表达式作为属性

Swift 复制代码
class Calculator {
    // 定义一个闭包属性,该闭包接受两个 Int 类型的参数并返回一个 Int 类型的值
    var addition: (Int, Int) -> Int

    init(addition: @escaping (Int, Int) -> Int) {
        self.addition = addition
    }

    func performAddition(_ a: Int, _ b: Int) -> Int {
        return addition(a, b)
    }
}

// 创建一个 Calculator 实例,并传入一个闭包表达式
let calculator = Calculator { (a, b) in
    return a + b
}

// 使用闭包属性进行加法运算
let result = calculator.performAddition(5, 3)
print("5 + 3 = \(result)")    

1.3、oc 闭包表达式作为参数的形式

Swift 复制代码
#import <Foundation/Foundation.h>

// 定义一个带有block参数的函数
void performOperation(int a, int b, int (^operation)(int, int)) {
    int result = operation(a, b);
    NSLog(@"计算结果: %d", result);
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 定义一个block
        int (^add)(int, int) = ^(int x, int y) {
            return x + y;
        };

        // 调用函数并传递block
        performOperation(5, 3, add);

        // 也可以直接传递匿名block
        performOperation(5, 3, ^(int x, int y) {
            return x * y;
        });
    }
    return 0;
}

1.4、oc 闭包表达式作为属性

Swift 复制代码
#import <Foundation/Foundation.h>

// 定义一个包含 block 属性的类
@interface MyClass : NSObject

// 声明一个 block 属性
@property (nonatomic, copy) void (^myBlock)(NSString *);

// 一个方法,用于调用 block
- (void)invokeBlockWithMessage:(NSString *)message;

@end

@implementation MyClass

- (void)invokeBlockWithMessage:(NSString *)message {
    if (self.myBlock) {
        self.myBlock(message);
    }
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 创建 MyClass 实例
        MyClass *myObject = [[MyClass alloc] init];
        
        // 设置 block 属性
        myObject.myBlock = ^(NSString *message) {
            NSLog(@"接收到的消息: %@", message);
        };
        
        // 调用方法触发 block
        [myObject invokeBlockWithMessage:@"Hello, Block!"];
    }
    return 0;
}

二、代理

2.1、swift 代理表达式作为参数的形式

Swift 复制代码
// 定义代理协议
protocol MyDelegate: AnyObject {
    func didSomething()
}

// 一个类,接收代理作为参数
class MyClass {
    weak var delegate: MyDelegate?

    init(delegate: MyDelegate) {
        self.delegate = delegate
    }

    func performAction() {
        // 模拟执行某些操作
        print("Performing an action...")
        // 操作完成后调用代理方法
        delegate?.didSomething()
    }
}

// 实现代理协议的类
class MyViewController: MyDelegate {
    func didSomething() {
        print("Delegate method called.")
    }
}

// 使用示例
let viewController = MyViewController()
let myClass = MyClass(delegate: viewController)
myClass.performAction()

2.2、swift 代理表达式作为属性

Swift 复制代码
定义协议
swift
protocol ButtonClickDelegate: AnyObject {
    func buttonDidClick()
}

这里定义了一个协议 ButtonClickDelegate,声明了一个方法 buttonDidClick,表示按钮点击时要执行的操作。AnyObject 表明该协议只能被类遵循,结构体和枚举不能遵循。
创建视图控制器类并设置代理属性
swift
class ViewController: UIViewController {
    weak var buttonDelegate: ButtonClickDelegate?
    
    @IBAction func buttonTapped(_ sender: UIButton) {
        buttonDelegate?.buttonDidClick()
    }
}
在 ViewController 类中,定义了一个可选的、弱引用的代理属性 buttonDelegate,遵循 ButtonClickDelegate 协议。当按钮被点击时,调用代理的 buttonDidClick 方法。
创建另一个类遵循协议并实现方法
swift
class AnotherClass: ButtonClickDelegate {
    func buttonDidClick() {
        print("按钮被点击了!")
    }
}
AnotherClass 遵循 ButtonClickDelegate 协议,并实现了 buttonDidClick 方法,在方法中打印提示信息。
设置代理并测试
swift
let viewController = ViewController()
let another = AnotherClass()
viewController.buttonDelegate = another
// 模拟按钮点击(实际开发中由用户操作触发)
viewController.buttonTapped(UIButton()) 
通过设置 viewController 的 buttonDelegate 为 another,当按钮点击时,AnotherClass 中的 buttonDidClick 方法就会被调用。

2.3、oc 代理表达式作为参数的形式

Swift 复制代码
#import <Foundation/Foundation.h>

// 定义代理协议
@protocol DataLoaderDelegate <NSObject>

// 数据加载成功的回调方法
- (void)dataLoaderDidFinishLoading:(NSData *)data;
// 数据加载失败的回调方法
- (void)dataLoaderDidFailWithError:(NSError *)error;

@end

// 数据加载器类
@interface DataLoader : NSObject

// 加载数据的方法,接受代理对象作为参数
- (void)loadDataWithDelegate:(id<DataLoaderDelegate>)delegate;

@end

@implementation DataLoader

- (void)loadDataWithDelegate:(id<DataLoaderDelegate>)delegate {
    // 模拟数据加载过程
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 模拟耗时操作
        sleep(2);
        // 模拟成功或失败
        BOOL success = arc4random_uniform(2) == 0;
        if (success) {
            // 模拟成功加载的数据
            NSData *data = [@"This is loaded data" dataUsingEncoding:NSUTF8StringEncoding];
            dispatch_async(dispatch_get_main_queue(), ^{
                [delegate dataLoaderDidFinishLoading:data];
            });
        } else {
            // 模拟加载失败的错误
            NSError *error = [NSError errorWithDomain:@"DataLoaderErrorDomain" code:1 userInfo:@{NSLocalizedDescriptionKey: @"Failed to load data"}];
            dispatch_async(dispatch_get_main_queue(), ^{
                [delegate dataLoaderDidFailWithError:error];
            });
        }
    });
}

@end

// 实现代理协议的类
@interface ViewController : NSObject <DataLoaderDelegate>

- (void)startLoadingData;

@end

@implementation ViewController

- (void)startLoadingData {
    DataLoader *loader = [[DataLoader alloc] init];
    [loader loadDataWithDelegate:self];
}

- (void)dataLoaderDidFinishLoading:(NSData *)data {
    NSString *loadedString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"Data loaded successfully: %@", loadedString);
}

- (void)dataLoaderDidFailWithError:(NSError *)error {
    NSLog(@"Data loading failed: %@", error.localizedDescription);
}

@end

// 主函数
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        ViewController *vc = [[ViewController alloc] init];
        [vc startLoadingData];
        // 为了模拟异步操作,这里简单等待一段时间
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5]];
    }
    return 0;
}

2.4、oc 代理 闭包表达式作为属性

Swift 复制代码
#import <Foundation/Foundation.h>

// 定义代理协议
@protocol DownloadManagerDelegate <NSObject>

@optional
// 下载完成的回调方法
- (void)downloadManagerDidFinishDownloading:(NSString *)filePath;
// 下载失败的回调方法
- (void)downloadManagerDidFailWithError:(NSError *)error;

@end

// 下载管理类
@interface DownloadManager : NSObject

// 声明代理属性,使用 weak 修饰符避免循环引用
@property (nonatomic, weak) id<DownloadManagerDelegate> delegate;

// 开始下载的方法
- (void)startDownloading;

@end

@implementation DownloadManager

- (void)startDownloading {
    // 模拟下载过程
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 模拟耗时操作
        sleep(2);
        // 模拟成功或失败
        BOOL success = arc4random_uniform(2) == 0;
        if (success) {
            NSString *filePath = @"/path/to/downloaded/file";
            dispatch_async(dispatch_get_main_queue(), ^{
                if ([self.delegate respondsToSelector:@selector(downloadManagerDidFinishDownloading:)]) {
                    [self.delegate downloadManagerDidFinishDownloading:filePath];
                }
            });
        } else {
            NSError *error = [NSError errorWithDomain:@"DownloadErrorDomain" code:1 userInfo:@{NSLocalizedDescriptionKey: @"Download failed"}];
            dispatch_async(dispatch_get_main_queue(), ^{
                if ([self.delegate respondsToSelector:@selector(downloadManagerDidFailWithError:)]) {
                    [self.delegate downloadManagerDidFailWithError:error];
                }
            });
        }
    });
}

@end

// 实现代理协议的类
@interface ViewController : NSObject <DownloadManagerDelegate>

- (void)startDownload;

@end

@implementation ViewController

- (void)startDownload {
    DownloadManager *manager = [[DownloadManager alloc] init];
    manager.delegate = self;
    [manager startDownloading];
}

- (void)downloadManagerDidFinishDownloading:(NSString *)filePath {
    NSLog(@"Download finished. File path: %@", filePath);
}

- (void)downloadManagerDidFailWithError:(NSError *)error {
    NSLog(@"Download failed: %@", error.localizedDescription);
}

@end

// 主函数
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        ViewController *vc = [[ViewController alloc] init];
        [vc startDownload];
        // 为了模拟异步操作,这里简单等待一段时间
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5]];
    }
    return 0;
}    
相关推荐
赵和范5 分钟前
C++:书架
开发语言·c++·算法
boooo_hhh35 分钟前
第J7周:对于ResNeXt-50算法的思考
开发语言·python·深度学习
LSL666_1 小时前
Java——多态
java·开发语言·多态·内存图
麓殇⊙1 小时前
CurrentHashMap的整体系统介绍及Java内存模型(JVM)介绍
java·开发语言·jvm
LSL666_2 小时前
Java——包装类
java·开发语言·包装类
yasuniko2 小时前
C++线程库
开发语言·c++
@老蝴2 小时前
C语言—指针2
c语言·开发语言
明月看潮生2 小时前
青少年编程与数学 02-019 Rust 编程基础 01课题、环境准备
开发语言·青少年编程·rust·编程与数学
VBA63372 小时前
VBA高级应用30例应用4:利用屏蔽事件来阻止自动运行事件
开发语言
Pop–3 小时前
Vue3 el-tree:全选时只返回父节点,半选只返回勾选中的节点(省-市区-县-镇-乡-村-街道)
开发语言·javascript·vue.js