ios – 委托函数vs回调函数

ios – 委托函数vs回调函数,第1张

概述参见英文答案 > Problem understanding Delegating pattern & callback functions in Objective C                                    3 我在iOS平台上工作,我想知道什么是代理功能,什么是回调函数?两种功能的区别是什么? 代理函数的例子是UITableViewDelegate协议中的num 参见英文答案 > Problem understanding Delegating pattern & callback functions in Objective C3
我在iOS平台上工作,我想知道什么是代理功能,什么是回调函数?两种功能的区别是什么?

代理函数的例子是UItableVIEwDelegate协议中的numberOfRowsInSection和回调函数的示例是appDelegate.m中的dIDReceivelocalnotification

我们可以在Objective-C中创建自己的回调函数,如果是,给出一个例子…

谢谢..

解决方法 几个想法:

>你建议didReceiveLocationNotification是一个“回调函数”,但它实际上只是UIApplicationDelegate协议的委托方法.所以,numberOfRowsInSection和dIDReceivelocalnotification都是简单的委托方法.

与调用NSTimer或定义UIGestureRecognizer的处理程序相比,类似于通用回调函数的选择器将是选择器,其中方法名称的选择不是预先确定的.

或者回调在CFArray被广泛使用.
>但是,您的问题的根源不在于术语,而是一个如何定义一个接口的问题,其中调用者可以指定某个其他对象将来某个日期将异步地调用(异步)的方法.有几种常见的模式:

> Block parameter to method:定义以块为参数的方法越来越常见.例如,您可以使用如下定义的方法:

- (NSURLSessionTask *)downloadAsynchronously:(NSURL *)url filename:(Nsstring *)filename completion:(voID (^)(NSData *results,Nsstring *filename))completion {    NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data,NSURLResponse *response,NSError *error) {        dispatch_async(dispatch_get_main_queue(),^{            completion(data,filename);        });    }];    [task resume];    return task;}

第三个参数,完成,是一个代码块,将被下载完成.因此,您可以如下调用该方法:

[self downloadAsynchronously:url filename:filename completion:^(NSData *results,Nsstring *filename) {    NSLog(@"Downloaded %d bytes",[results length]);    [results writetofile:filename atomically:YES];}];NSLog(@"%s done",__FUNCTION__);

您将看到“完成”消息立即显示,并且完成该块将在下载完成时被调用.它确实需要一段时间才能习惯于构成块变量/参数定义的标点符号,但是一旦你熟悉了这个块语法,你就会很欣赏这个模式.它消除了调用某些方法和定义一些单独的回调函数之间的断开连接.

如果要简化处理块作为参数的语法,您可以实际为您的完成块定义一个typedef:

typedef voID (^DownloadCompletionBlock)(NSData *results,Nsstring *filename);

然后方法声明本身就简化了:

- (NSURLSessionTask *)downloadAsynchronously:(NSURL *)url filename:(Nsstring *)filename completion:(DownloadCompletionBlock)completion {    NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data,filename);        });    }];    [task resume];    return task;}

> Delegate-protocol pattern:对象之间通信的另一种常用技术是委托协议模式.首先,您定义协议(“回调”接口的性质):

@protocol DownloadDelegate <NSObject>- (NSURLSessionTask *)dIDFinishedDownload:(NSData *)data filename:(Nsstring *)filename;@end

然后,您定义将调用此DownloadDelegate方法的类:

@interface Downloader : NSObject@property (nonatomic,weak) ID<DownloadDelegate> delegate;- (instancetype)initWithDelegate:(ID<DownloadDelegate>)delegate;- (NSURLSessionTask *)downloadAsynchronously:(NSURL *)url filename:(Nsstring *)filename;@end@implementation Downloader- (instancetype)initWithDelegate:(ID<DownloadDelegate>)delegate {    self = [super init];    if (self) {        _delegate = delegate;    }    return self;}- (NSURLSessionTask *)downloadAsynchronously:(NSURL *)url filename:(Nsstring *)filename {    NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data,^{            [self.delegate dIDFinishedDownload:data filename:filename];        });    }];    [task resume];    return task;}@end

最后,使用这个新的Downloader类的原始视图控制器必须符合DownloadDelegate协议:

@interface VIEwController () <DownloadDelegate>@end

并定义协议方法:

- (voID)dIDFinishedDownload:(NSData *)data filename:(Nsstring *)filename {    NSLog(@"Downloaded %d bytes",[data length]);    [data writetofile:filename atomically:YES];}

并执行下载:

Downloader *downloader = [[Downloader alloc] initWithDelegate:self];[downloader downloadAsynchronously:url filename:filename];NSLog(@"%s done",__FUNCTION__);

> Selector pattern:您在某些Cocoa对象(例如NSTimer,UIPanGestureRecognizer)中看到的模式是将选择器作为参数传递的概念.例如,我们可以定义我们的下载方法如下:

- (NSURLSessionTask *)downloadAsynchronously:(NSURL *)url filename:(Nsstring *)filename target:(ID)target selector:(SEL)selector {    ID __weak weakTarget = target; // so that the dispatch_async won't retain the selector    NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data,^{#pragma clang diagnostic push#pragma clang diagnostic ignored "-Warc-performSelector-leaks"            [weakTarget performSelector:selector                             withObject:data                             withObject:filename];#pragma clang diagnostic pop        });    }];    [task resume];    return task;}

然后你会调用如下:

[self downloadAsynchronously:url                    filename:filename                      target:self                    selector:@selector(dIDFinishedDownload:filename:)];

但是,您还必须定义在下载完成时将调用的单独方法:

- (voID)dIDFinishedDownload:(NSData *)data filename:(Nsstring *)filename {    NSLog(@"Downloaded %d bytes",[data length]);    [data writetofile:filename atomically:YES];}

就个人而言,我发现这种模式太脆弱,依赖协调接口而无需编译器的任何帮助.但是,由于这种模式在Cocoa的老版本中使用相当多,所以我将其包含在一些历史参考中.
> Notifications:提供一些异步方法的其他机制是发送本地通知.当(a)网络请求的结果的潜在接收者在请求启动时是未知的,这通常是最有用的;或(b)可能会有多个类别希望被通知此事件.因此,网络请求可以在完成后发布特定名称的通知,并且任何有兴趣被通知此事件的对象可以通过NSNotificationCenter将自己添加为本地通知的观察者.

这不是一个“回调”本身,而是代表一个对象被通知完成一些异步任务的另一个模式.

这些是“回调”模式的几个例子.显然,所提供的例子是任意的和微不足道的,但希望它能给你一个你的选择的想法.现在最常用的两种技术是块和委托模式.当需要简单而优雅的界面时,块越来越受到青睐.但是对于丰富而复杂的界面,代表们很常见.

总结

以上是内存溢出为你收集整理的ios – 委托函数vs回调函数全部内容,希望文章能够帮你解决ios – 委托函数vs回调函数所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1111448.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存