一、闭包或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;
}