将 'NSError *const __strong *' 发送到 'NSError *__autoreleasing *' 类型的参数会更改指针的 retain/release 属性
Sending 'NSError *const __strong *' to parameter of type 'NSError *__autoreleasing *' changes retain/release properties of pointer
这个问题与 ios NSError types 类似,但是那里描述的解决方案没有用,我认为这不是我需要的。
我有一个方法执行异步调用,然后调用完成块。当我尝试将 NSError ** 传递给完成块时,出现此错误:
Sending 'NSError *const __strong *' to parameter of type 'NSError
*__autoreleasing *' changes retain/release properties of pointer
代码如下:
+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock
{
dispatch_queue_t requestQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(requestQueue, ^{
NSString * parameterizedUrl = [AKAgentProfileEndPoint stringByAppendingString:guid];
NSURL *url = [NSURL URLWithString:parameterizedUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError * error = nil;
AKAgentProfile * agentProfile = [[[AKAgentFactory alloc] init] agentProfileWithData:data error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(agentProfile,&error);
});
});
}
按值传递错误,而不是按引用传递错误,即将块签名更改为 void (^)(AKAgentProfile * agentProfile, NSError * error)
并传递 error
而不是 &error
。
您在
中将错误定义为参数
+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock
然后再次在块中,我建议您将块中的那个重命名为:
+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock
{
dispatch_queue_t requestQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(requestQueue, ^{
NSString * parameterizedUrl = [AKAgentProfileEndPoint stringByAppendingString:guid];
NSURL *url = [NSURL URLWithString:parameterizedUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError * err = nil;
AKAgentProfile * agentProfile = [[[AKAgentFactory alloc] init] agentProfileWithData:data error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(agentProfile,&err);
});
});
}
您的完成块参数完全是胡说八道。
调用堆栈上有一个变量 NSError* err。
然后您尝试将 err 的地址传递给将在主线程中调用的完成块。到调用完成块时,您的函数早已返回,并且 &err 是垃圾。如果完成块试图在那里存储任何东西,它会在很久以前你的 err 变量在堆栈上的地方存储一个 NSError* ,很可能会覆盖一个完全不相关的方法的一些有价值的数据。
这不适用于回调块。
这个问题与 ios NSError types 类似,但是那里描述的解决方案没有用,我认为这不是我需要的。
我有一个方法执行异步调用,然后调用完成块。当我尝试将 NSError ** 传递给完成块时,出现此错误:
Sending 'NSError *const __strong *' to parameter of type 'NSError *__autoreleasing *' changes retain/release properties of pointer
代码如下:
+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock
{
dispatch_queue_t requestQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(requestQueue, ^{
NSString * parameterizedUrl = [AKAgentProfileEndPoint stringByAppendingString:guid];
NSURL *url = [NSURL URLWithString:parameterizedUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError * error = nil;
AKAgentProfile * agentProfile = [[[AKAgentFactory alloc] init] agentProfileWithData:data error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(agentProfile,&error);
});
});
}
按值传递错误,而不是按引用传递错误,即将块签名更改为 void (^)(AKAgentProfile * agentProfile, NSError * error)
并传递 error
而不是 &error
。
您在
中将错误定义为参数+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock
然后再次在块中,我建议您将块中的那个重命名为:
+(void) agentWithGUID:(NSString *) guid completion:(void (^)(AKAgentProfile * agentProfile, NSError ** error)) completionBlock
{
dispatch_queue_t requestQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(requestQueue, ^{
NSString * parameterizedUrl = [AKAgentProfileEndPoint stringByAppendingString:guid];
NSURL *url = [NSURL URLWithString:parameterizedUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError * err = nil;
AKAgentProfile * agentProfile = [[[AKAgentFactory alloc] init] agentProfileWithData:data error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(agentProfile,&err);
});
});
}
您的完成块参数完全是胡说八道。
调用堆栈上有一个变量 NSError* err。
然后您尝试将 err 的地址传递给将在主线程中调用的完成块。到调用完成块时,您的函数早已返回,并且 &err 是垃圾。如果完成块试图在那里存储任何东西,它会在很久以前你的 err 变量在堆栈上的地方存储一个 NSError* ,很可能会覆盖一个完全不相关的方法的一些有价值的数据。
这不适用于回调块。