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;
}    
相关推荐
SRC_BLUE_177 分钟前
Python GUI 编程 | QAbstractButton 抽象按钮类详解 — 按钮状态设置
开发语言·python
双叶8368 分钟前
(C语言)双向链表(教程)(指针)(数据结构)
c语言·开发语言·数据结构·c++·链表
珊瑚里的鱼17 分钟前
【双指针】专题:LeetCode 283题解——移动零
开发语言·c++·笔记·算法·leetcode·职场和发展
keli_Jun44 分钟前
Java常见面试问题
java·开发语言·spring boot
努力学习的小廉44 分钟前
【C++】 —— 笔试刷题day_15
开发语言·c++
风中飘爻2 小时前
JavaScript:BOM编程
开发语言·javascript·ecmascript
kyle~2 小时前
ROS2---std_msgs基础消息包
开发语言·python·机器人·ros·机器人操作系统
满怀10152 小时前
【NumPy科学计算引擎:从基础操作到高性能实践】
开发语言·python·numpy
我命由我123453 小时前
35.Java线程池(线程池概述、线程池的架构、线程池的种类与创建、线程池的底层原理、线程池的工作流程、线程池的拒绝策略、自定义线程池)
java·服务器·开发语言·jvm·后端·架构·java-ee
&zzz3 小时前
Python生成exe
开发语言·python