如何解决返回NSString时出现的不兼容块指针类型编译错误?
问题分析与解决办法
直接编译错误原因
你遇到的编译错误核心在于Firebase的observeSingleEventOfType:withBlock:方法要求传入的block是无返回值(void)的,但你写的block却返回了NSString *类型,这就导致了块指针类型不匹配——系统期望接收一个void (^)(FIRDataSnapshot *)的block,你却传了一个NSString *(^)(FIRDataSnapshot *)的block,自然会报错。
更深层的逻辑问题
除了编译错误,你的代码还有一个本质设计问题:Firebase的数据库读取是异步操作,网络请求不会立即返回结果。你试图让这个类方法同步返回fifeScore,但实际上方法本身会在网络请求完成前就执行完毕,根本拿不到正确的结果。
解决办法:改用异步回调(Completion Block)
正确的做法是修改方法设计,通过completion block来传递异步获取到的分数,而不是同步返回。具体代码如下:
+ (void)getFifeScoreForUserWithUID:(NSString *)uid completion:(void (^)(NSString *fifeScore))completion { FIRDatabaseReference *scoreRef = [[[[FIRDatabase database] reference] child:@"Scores"] child:uid]; [scoreRef observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) { NSString *fifeScore; if (snapshot.exists) { NSString *tempScore = [snapshot.value objectForKey:@"fifeScore"]; fifeScore = [NSString stringWithFormat:@"%@", tempScore]; } else { fifeScore = @"0"; } // 通过completion block把结果传递出去 if (completion) { completion(fifeScore); } } withCancelBlock:^(NSError *error) { // 处理请求失败的情况,这里默认返回0,也可以把错误信息一起传给completion if (completion) { completion(@"0"); } NSLog(@"获取Fife分数失败:%@", error.localizedDescription); }]; }
调用方式
当你需要获取分数时,通过completion block来接收结果并做后续操作(比如更新UI):
// 替换成你的类名 [YourClass getFifeScoreForUserWithUID:@"目标用户UID" completion:^(NSString *fifeScore) { // 在这里拿到分数,执行后续逻辑 NSLog(@"用户的Fife分数是:%@", fifeScore); // 如果要更新UI,记得切回主线程(Firebase的block默认在后台线程执行) dispatch_async(dispatch_get_main_queue(), ^{ // 比如更新UILabel的文本 self.scoreLabel.text = fifeScore; }); }];
补充说明
为什么不能同步返回?因为网络请求需要时间,同步等待会阻塞主线程,导致APP界面卡顿、无响应,严重时会被系统判定为“未响应”而杀死。iOS开发中所有涉及网络、IO的操作,都推荐用异步回调的方式处理。
内容的提问来源于stack exchange,提问作者Austin Berenyi
相关产品推荐
相关产品推荐

