如何在Objective-C协议方法中传递匿名结构体?
解决Objective-C协议中匿名结构体参数的调用报错问题
为什么会报错?
你写的代码之所以报错,是因为协议方法里定义的匿名结构体,和你调用时单独声明的匿名结构体,是两个完全独立的类型——哪怕它们的成员完全一样,编译器也会判定类型不兼容,所以没法直接传递。
可行的解决办法
1. 给结构体加个名字(最推荐)
如果能修改协议的话,直接给匿名结构体加上名称,这样整个代码里都用同一个类型:
// 修改后的协议 @protocol testp typedef struct { int a; } TestStruct; - (void)testMethod:(TestStruct)arg1 reply:(void (^)(NSError *))arg2; @end
调用的时候直接用这个命名好的结构体就行:
TestStruct test = {1}; [p testMethod:test reply:^(NSError* error ){ NSLog(@"error: %@", error); }];
2. 直接用复合字面量传参
要是协议没法改(比如是第三方提供的),可以直接在调用方法的时候用C99复合字面量构造结构体,这样编译器会把它识别成和协议里一致的匿名结构体:
[p testMethod:(struct {int a;}){1} reply:^(NSError* error ){ NSLog(@"error: %@", error); }];
这种方式不用单独声明变量,直接在参数位置构造结构体就行。
3. 用typedef给匿名结构体起别名
如果协议不能修改,还可以通过typedef复用协议里的匿名结构体类型:
// 先给协议里的结构体类型起别名 typedef struct {int a;} TestStruct; // 调用时使用这个别名 TestStruct test = {1}; [p testMethod:test reply:^(NSError* error ){ NSLog(@"error: %@", error); }];
这么做的本质是让你调用时用的结构体类型,和协议里的完全一致,编译器就能识别了。
内容的提问来源于stack exchange,提问作者ph0rex
相关产品推荐
相关产品推荐

