我在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回调函数所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)