Java接口转Objective-C实现咨询:多回调对象传递问题
嘿,作为从Java转OC踩过不少坑的过来人,你的需求刚好可以用**Objective-C的协议(Protocol)**完美解决——这玩意就相当于Java里的Interface,既能承载多个回调方法,还能顺畅和C代码交互。下面我一步步给你拆解实现:
1. 定义对应Java接口的OC协议
首先我们把Java里的MyInterface转成OC的协议,语法很直观:
// 对应Java的MyInterface,<NSObject>让协议能被NSObject子类实现 @protocol MyCallbackProtocol <NSObject> - (void)onSuccess:(NSString *)message; - (void)onError:(NSString *)errorMessage; @end
这就和你Java里的接口功能完全一致,用来规范回调方法的签名。
2. 实现协议(对应Java的匿名内部类)
OC里没有直接的匿名内部类,但我们有两种方式实现类似效果:
方式一:常规类实现(适合复用的回调逻辑)
如果你的回调逻辑需要复用,直接写个类实现协议就行:
@interface MyCallbackHandler : NSObject <MyCallbackProtocol> @end @implementation MyCallbackHandler - (void)onSuccess:(NSString *)message { NSLog(@"收到成功回调:%@", message); // 这里写你原来Java匿名类里的业务逻辑 } - (void)onError:(NSString *)errorMessage { NSLog(@"收到错误回调:%@", errorMessage); // 错误处理逻辑放这 } @end
方式二:Block桥接类(模拟Java匿名类的一次性实现)
如果想要像Java匿名类那样写一次性的回调逻辑,可以封装一个用Block实现协议的桥接类,用起来更灵活:
@interface BlockBasedCallbackHandler : NSObject <MyCallbackProtocol> @property (nonatomic, copy) void(^successBlock)(NSString *); @property (nonatomic, copy) void(^errorBlock)(NSString *); + (instancetype)handlerWithSuccess:(void(^)(NSString *))success error:(void(^)(NSString *))error; @end @implementation BlockBasedCallbackHandler + (instancetype)handlerWithSuccess:(void(^)(NSString *))success error:(void(^)(NSString *))error { BlockBasedCallbackHandler *handler = [[self alloc] init]; handler.successBlock = success; handler.errorBlock = error; return handler; } - (void)onSuccess:(NSString *)message { if (self.successBlock) self.successBlock(message); } - (void)onError:(NSString *)errorMessage { if (self.errorBlock) self.errorBlock(errorMessage); } @end
用的时候就像写匿名类一样简洁:
id<MyCallbackProtocol> callback = [BlockBasedCallbackHandler handlerWithSuccess:^(NSString *message) { NSLog(@"成功:%@", message); } error:^(NSString *errorMessage) { NSLog(@"错误:%@", errorMessage); }];
3. 把回调实例传递给C方法
C方法不能直接处理OC对象,所以我们需要把OC对象转成void*指针传递,之后在C方法里再转回来调用回调:
首先定义你的C方法:
// C方法,接收回调对象的void*指针 void performTaskWithCallback(void *callbackPtr) { // 用__bridge把void*转成OC协议对象,注意ARC下的内存管理 id<MyCallbackProtocol> callback = (__bridge id<MyCallbackProtocol>)callbackPtr; // 模拟业务逻辑,调用成功回调 [callback onSuccess:@"任务执行完成"]; // 如果是错误场景就调用error回调 // [callback onError:@"任务执行失败"]; }
然后在OC代码里调用这个C方法:
// 创建回调实例(两种方式选一种) id<MyCallbackProtocol> callback = [[MyCallbackHandler alloc] init]; // id<MyCallbackProtocol> callback = [BlockBasedCallbackHandler handlerWithSuccess:... error:...]; // 用__bridge转成void*传递给C方法 performTaskWithCallback((__bridge void*)callback);
注意:异步场景的内存管理
如果你的C方法是异步执行的(比如后台任务),要避免回调对象被ARC提前释放,这时候需要用__bridge_retained转移所有权,在C方法完成后再用__bridge_transfer转回ARC自动释放:
// 异步场景下,先保留对象 void *callbackPtr = (__bridge_retained void*)callback; performAsyncTaskWithCallback(callbackPtr); // 在C方法的异步回调里: id<MyCallbackProtocol> callback = (__bridge_transfer id<MyCallbackProtocol>)callbackPtr; [callback onSuccess:@"异步任务完成"]; // __bridge_transfer会把所有权交回ARC,自动帮你释放对象
为什么不用多个Block直接传递?
你提到Block适合单回调,其实多回调也能传多个Block给C方法,但这样C方法的参数会变得冗长,而且当回调方法增多时,协议的方式更清晰,也更贴近你熟悉的Java接口思路,维护起来更方便。
内容的提问来源于stack exchange,提问作者Barterio
相关产品推荐
相关产品推荐

