IOS 回调函数实现方法
来源:互联网 发布:ben carson 知乎 编辑:程序博客网 时间:2024/06/11 21:32
IOS中实现回调的三种方式
typedef void (^Success)(NSMutableArray *resultArray);
typedef void (^Faile)(NSString *errorMsg);
@interface GASSFlightPlanParse : NSObject<GetDataFromServerDone]] >
{
NSMutableArray *_flightPlanObjects;
Success sucessBlock;
Faile faileBlock;
}
@property (nonatomic,strong) NSMutableArray *flightPlanObjects;
- (id) initWithObjectByDate:(NSString *) date
completionBlock:(void(^)(NSMutableArray* resultArray)) success
failBlock:(void(^)(NSString *errorMsg)) fail;
@end
{
[self.searchBar setText:self.searchText];
NSString *date = [self.searchText stringByReplacingOccurrencesOfString:@"-" withString:@""];
void (^Success)(NSMutableArray *result) = ^(NSMutableArray *result)
{
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^
{
if ([result count] == 0)
{
[self alterMessage:NSLocalizedString(@"NoFlightPlanData", @"")];
return;
}
if (self.flightPlanObjectsArray!= nil)
{
[self.flightPlanObjectsArray removeAllObjects];
self.flightPlanObjectsArray = nil;
}
[self.flightPlanObjectsArray addObjectsFromArray:result];
self.selectedIndexPath = -1;
[self.myTableView reloadData];
});
};
void (^Fail) (NSString *errorMsg) = ^(NSString *errorMsg)
{
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
[self alterMessage:errorMsg];
});
};
GASSFlightPlanParse *parse = [[GASSFlightPlanParse alloc] initWithObjectByDate:date completionBlock:Success failBlock:Fail];
parse = nil;
}
* 函数描述:
* 飞行计划
*
*
******************************************************************/
- (void) getFlightPlaneByDate
{
[self.searchBar setText:self.searchText];
NSString *date = [self.searchText stringByReplacingOccurrencesOfString:@"-" withString:@""];
GASSFlightPlanParse *parse = [[GASSFlightPlanParse alloc] initWithObject:self withDate:date];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reloadPlanData:)
name:KGetFlightPlanDataFromServer
object:parse];
[UIApplication sharedApplication]. networkActivityIndicatorVisible = YES;
}
- (void) reloadPlanData:(NSNotification *) notification
{
[self performSelectorOnMainThread:@selector(reloadFlightPlanData:)
withObject:notification
waitUntilDone:YES];
}
- (void) reloadFlightPlanData:(NSNotification *) notification
{
GASSFlightPlanParse *parse = (GASSFlightPlanParse *)[notification object];
if ([parse.flightPlanObjects count] == 0)
{
[self alterMessage:@"暂无飞行计划信息,请稍后刷新!"];
return;
}
if (self.flightPlanObjectsArray!= nil)
{
[self.flightPlanObjectsArray removeAllObjects];
self.flightPlanObjectsArray = nil;
}
[self.flightPlanObjectsArray addObjectsFromArray:parse.flightPlanObjects];
parse = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:KGetFlightPlanDataFromServer object:parse];
self.selectedIndexPath = -1;
[self.myTableView reloadData];
}
{
//Do something…………
//.…………
经常使用到的两种类
业务逻辑类:控制主要的业务逻辑 数据获取和加工
工具类:进行网络连接 获取网络资源类耗时操作等
1.协议+代理
UtilNetWork.h 文件
@protocol GetDataFromServerDone;
@interface UtilNetWork : NSObject
+(void) getJSonDataFromServer:(NSString*)query object:(id<GetDataFromServerDone>) delegate;
@end
@protocol GetDataFromServerDone
- (void) GetJSonDataFromServer:(id) data;
@end
UtilNetWork.m 文件
#import "UtilNetWork.h"
#import "AFJSONRequestOperation.h"
@implementation UtilNetWork
+ (void) getJSonDataFromServer:(NSString*)query object:(id<GetDataFromServerDone>) delegate
{
__block NSDictionary *result = nil;
NSURL *serverURL = [NSURL URLWithString:query];
NSURLRequest *request = [NSURLRequest requestWithURL:serverURL];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
result = (NSDictionary *)JSON;
[delegate GetJSonDataFromServer:result];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)
{
[delegate GetJSonDataFromServer:nil];
}];
[operation start];
}
@end
工具类:进行网络连接 获取网络资源类耗时操作等
1.协议+代理
UtilNetWork.h 文件
@protocol GetDataFromServerDone;
@interface UtilNetWork : NSObject
+(void) getJSonDataFromServer:(NSString*)query object:(id<GetDataFromServerDone>) delegate;
@end
@protocol GetDataFromServerDone
- (void) GetJSonDataFromServer:(id) data;
@end
UtilNetWork.m 文件
#import "UtilNetWork.h"
#import "AFJSONRequestOperation.h"
@implementation UtilNetWork
+ (void) getJSonDataFromServer:(NSString*)query object:(id<GetDataFromServerDone>) delegate
{
__block NSDictionary *result = nil;
NSURL *serverURL = [NSURL URLWithString:query];
NSURLRequest *request = [NSURLRequest requestWithURL:serverURL];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
result = (NSDictionary *)JSON;
[delegate GetJSonDataFromServer:result];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)
{
[delegate GetJSonDataFromServer:nil];
}];
[operation start];
}
@end
UtilNetWork类负责连网操作的工具类,用来从指定的服务器获得JSon 数据。
在.h文件中定义了协议接口,任何想使用该类进行JSon获取的业务逻辑类必须要实现 GetDataFromServerDone这个协议,当从网络获取jSon数据后会回调用业务逻辑类实现的该方法。例如可以对获取到的JSon数据进行解析等。
2.使用代码块
IOS NSFoundation类库中大量使用了代码卡,例如NSArray和NSDictionary类里用于枚举数据元素的函数,NSURLConnection类的连网操作函数等。
我们也可以仿照其来定义自己的回调函数,把一些简单的逻辑操作封装到代码块中,当异步调用函数返回后会自动调用代码块。
例如:
typedef void (^Success)(NSMutableArray *resultArray);
typedef void (^Faile)(NSString *errorMsg);
@interface GASSFlightPlanParse : NSObject<GetDataFromServerDone]] >
{
NSMutableArray *_flightPlanObjects;
Success sucessBlock;
Faile faileBlock;
}
@property (nonatomic,strong) NSMutableArray *flightPlanObjects;
- (id) initWithObjectByDate:(NSString *) date
completionBlock:(void(^)(NSMutableArray* resultArray)) success
failBlock:(void(^)(NSString *errorMsg)) fail;
@end
该类是一个飞行计划的解析类,用来将从服务器获得指定日期的JSon数据封装成对象存储到flightPlanObjects数组中返回给业务逻辑类。
业务逻辑类调用初始化函数时,会传入两个代码块来处理当获取成功和失败的时候的操作。
当获取数据成功时,工具类通过调用代码块sucessBlock将数组flightPlanObjects传回给业务逻辑类;
当获取数据失败时,工具类会通过调用faileBlock将errorMsg传递给业务逻辑类。
下面时业务逻辑类的调用工具类的代码:
- (void) getFlightPlaneByDate{
[self.searchBar setText:self.searchText];
NSString *date = [self.searchText stringByReplacingOccurrencesOfString:@"-" withString:@""];
void (^Success)(NSMutableArray *result) = ^(NSMutableArray *result)
{
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^
{
if ([result count] == 0)
{
[self alterMessage:NSLocalizedString(@"NoFlightPlanData", @"")];
return;
}
if (self.flightPlanObjectsArray!= nil)
{
[self.flightPlanObjectsArray removeAllObjects];
self.flightPlanObjectsArray = nil;
}
[self.flightPlanObjectsArray addObjectsFromArray:result];
self.selectedIndexPath = -1;
[self.myTableView reloadData];
});
};
void (^Fail) (NSString *errorMsg) = ^(NSString *errorMsg)
{
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
[self alterMessage:errorMsg];
});
};
GASSFlightPlanParse *parse = [[GASSFlightPlanParse alloc] initWithObjectByDate:date completionBlock:Success failBlock:Fail];
parse = nil;
}
通过以上代码可以看到,当获取数据成功是Success代码块通过使用工具类传入的参数将结果保存到自己的数组里。同时,当失败的时候会在主线程中显示由工具类传入的错误消息
在这里代码块不仅封装了代码,而且还封装了数据,将业务逻辑类中的数据。
3.NSNotificationCenter
这种方法的使用比较简单,业务逻辑类只需要添加想要监听的Oberver, 然后工具类完成相应的操作后会想消息中心发送相应的消息,从而实现业务逻辑类和工具类之间的异步通信。
代码如下:
业务逻辑类:
/****************************************************************** 函数描述:
* 飞行计划
*
*
******************************************************************/
- (void) getFlightPlaneByDate
{
[self.searchBar setText:self.searchText];
NSString *date = [self.searchText stringByReplacingOccurrencesOfString:@"-" withString:@""];
GASSFlightPlanParse *parse = [[GASSFlightPlanParse alloc] initWithObject:self withDate:date];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reloadPlanData:)
name:KGetFlightPlanDataFromServer
object:parse];
[UIApplication sharedApplication]. networkActivityIndicatorVisible = YES;
}
- (void) reloadPlanData:(NSNotification *) notification
{
[self performSelectorOnMainThread:@selector(reloadFlightPlanData:)
withObject:notification
waitUntilDone:YES];
}
- (void) reloadFlightPlanData:(NSNotification *) notification
{
GASSFlightPlanParse *parse = (GASSFlightPlanParse *)[notification object];
if ([parse.flightPlanObjects count] == 0)
{
[self alterMessage:@"暂无飞行计划信息,请稍后刷新!"];
return;
}
if (self.flightPlanObjectsArray!= nil)
{
[self.flightPlanObjectsArray removeAllObjects];
self.flightPlanObjectsArray = nil;
}
[self.flightPlanObjectsArray addObjectsFromArray:parse.flightPlanObjects];
parse = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:KGetFlightPlanDataFromServer object:parse];
self.selectedIndexPath = -1;
[self.myTableView reloadData];
}
工具类:
-(void) parseFlightPlanModels{
//Do something…………
//.…………
//.….
[[NSNotificationCenter defaultCenter] postNotificationName:KGetFlightPlanDataFromServer
object:self];
}
[[NSNotificationCenter defaultCenter] postNotificationName:KGetFlightPlanDataFromServer
object:self];
}
4.工具类保存业务逻辑类的指针
在工具类进行初始化时,保存业务逻辑类的对象的指针,但相应操作完成后调用业务逻辑类的相关方法。
- (id) initWithObject:(GASSMasterViewController*)controller withDate:(NSString *) date;
总结:
1.以上四种方法是IOS开发过程中经常用到的异步函数实现回调的方法,其中前三种是推荐使用的,第四种代码的耦合性太高,最好不用。
2.通过比较这前三种的实现代码可以发现,代码块的方式比较简洁,NotificationCenter的方式比较好理解简单易容,协议+代理的方式
适合用于比较负责的业务逻辑。
3.在使用以上的代码模式类构建应用的时候一定要注意的问题是,工具类尤其是连网操作往往会在非UI线程中去执行,而当这样的操作执行
完毕后往往会执行一些与UI相关的操作,所以一定要确保这些操作要在主线程去执行,否则会出现一些意想不到的错误。
4.当代码块被引入IOS后,苹果官方文档鼓励使用代码块来实现异步操作,这样比使用代理的效率更高。
- IOS 回调函数实现方法
- PHP回调函数的实现方法
- PHP回调函数的实现方法
- PHP回调函数的实现方法
- PHP回调函数的实现方法
- ios回调函数
- IOS回调函数
- ios回调函数
- 回调函数实现
- [iOS]Objective-C利用协议实现回调函数(类似java的回调函数)
- [iOS]Objective-C利用协议实现回调函数(类似java的回调函数)
- [iOS]Objective-C利用协议实现回调函数(类似java的回调函数)
- [iOS]Objective-C利用协议实现回调函数(类似java的回调函数)
- [iOS]Objective-C利用协议实现回调函数(类似java的回调函数)
- ios中利用协议实现回调函数功能
- python 回调函数和回调方法的实现
- python 回调函数和回调方法的实现
- c#调用c++带有回调函数方法的实现
- 说说家乡的互联网-鸡西
- ExpandableListView 的用法
- Android签名与签名校验
- java 下载文件时中文出现乱码解决方案
- iOS多线程编程之NSThread的使用
- IOS 回调函数实现方法
- new对象构造函数执行顺序
- TDate类
- 给查询界面绑定query
- 三. ServerSocket 用法详解(一)
- 远程桌面连接终极解决方案
- VMware vCloud Networking and Security
- 文本框回车提交
- EJB到底是什么