项目中网络请求是一个是c写的UDP静态库。接口都是C的函数。
typedef void (*fun_ptr)(int, const char*, const char*);
void call_function(int cmd_id, const char* data, const char* source_id); // 发送请求
void set_call_back(fun_ptr callback_func); // 设置回调函数
回调函数显然也只能设置成c的函数,要对请求到的数据进行处理,就需要在C的函数里调用OC的方法。
百度搜索到的答案:
指定一个全局变量来保存类的地址,在通过类的地址找到类方法(函数)的地址调用。
从汇编角度来看:C函数也好OC方法也好,他们同样都是一个函数的地址。区别在于C函数调用直接通过 函数名(参数)找到函数指针 直接执行函数地址,不需要考虑其他问题,只要定义好 就能直接用 。
OC 是属于类的方法,结构上多了一层封装性,要调方法必须要找到 类的地址然后再通过类的地址找到方法的地址,然后再执行函数地址。
创建了一个网络请求的单例.h
#import <Foundation/Foundation.h>
typedef void(^NetWorkCallback)(int cmdId,NSData *data,const char *sourceId);
@interface NetWorkManager : NSObject
+(NetWorkManager *)shareManager;
-(void)netWorkRequest:(int)cmdID xmlData:(NSData *)xmlData sourceID:(const char*)sourceID complete:(NetWorkCallback)complete;
@end
.mm部分代码
@interface NetWorkManager ()
{
NetWorkCallback _block;
}
@end
@implementation NetWorkManager
NetWorkManager *netManager = nil; // 定义一个全局指针变量用于保存当前类的地址
// 回调函数
void callback_func1(int i, const char *data, const char *data2) {
NSLog(@"callback_func1");
[netManager socketBack:i xmlData:data sourceID:data2];
}
-(void)netWorkRequest:(int)cmdID xmlData:(NSData *)xmlData sourceID:(const char*)sourceID complete:(NetWorkCallback)complete
{
// 连接网络
// 处理data数据等
…………
netManager = self;//将函数self赋予全局函数指针
call_function(cmdID, data, sourceID);
set_call_back(callback_func1);
_block = complete;
}
-(void)socketBack:(int)cmdID xmlData:(const char*)xmlData sourceID:(const char*)sourceID
{
NSLog(@"进入OC回调函数");
NSString *xmlStr = [[NSString alloc]initWithUTF8String:xmlData];
NSData *data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding];
if (_block) {
_block(cmdID,data,sourceID);
}
}
调用
NetWorkManager *netWork = [NetWorkManager shareManager];
……构建请求需要的data数据 ……
[netWork netWorkRequest:xxxx xmlData:data sourceID:"xxxx" complete:^(int cmdId, NSData *data, const char *sourceId) {
……对获取的data数据进行处理……
}];