[英]Implicit conversion of a non-Objective-C pointer type void* to NSString*__strong* is disallowed with ARC
I got the above error when migrate to ARC. 迁移到ARC时出现上述错误。 Here is the code:
这是代码:
static NSString *cashBalanceKeyPath = @"test";
...
[xxx forKeyPath:cashBalanceKeyPath options:NSKeyValueObservingOptionNew context:&cashBalanceKeyPath];
...
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if (&cashBalanceKeyPath == context) < error here
{
...
}
When I used bridge: 当我使用电桥时:
if (&cashBalanceKeyPath == (__bridge NSString *)context)
I got the error: Comparison of distinct pointer types (NSString *__strong* and NSString *)
我收到错误:
Comparison of distinct pointer types (NSString *__strong* and NSString *)
How can I make the conversion? 我如何进行转换? Thanks in advance.
提前致谢。
I can't tell you exactly why, but you don't get a warning or error if you swap the order of the comparison: 我无法确切告诉您原因,但是如果您交换比较顺序,则不会收到警告或错误消息:
if (context == &cashBalanceKeyPath) {
// ...
}
You appear to be using the address of a variable as a unique tag, so there are no memory management/ownership issues here. 您似乎将变量的地址用作唯一标记,因此这里没有内存管理/所有权问题。 To do the address comparison cast the address of the variable to void:
要进行地址比较,请将变量的地址转换为void:
if ((void *)&cashBalanceKeyPath == context)
That seems to give the compiler all it needs without any bridge cast. 这似乎为编译器提供了所需的一切,而无需任何转换。
If you strip out the __strong
in the error message, it's clearer what's going on: 如果删除错误消息中的
__strong
, __strong
清楚了发生了什么:
Comparison of distinct pointer types (NSString ** and NSString *)
&cashBalanceKeyPath
is a pointer to an NSString object, or a NSString**
, while context is being cast to an NSString*
, or a plain NSString object (which it isn't). &cashBalanceKeyPath
是指向NSString对象或NSString**
的指针,而上下文则被&cashBalanceKeyPath
为NSString*
或普通NSString对象(不是)。
So to fix the problem, change the cast to be (NSString * const *)
, the const is apparently required to appease ARC. 因此,要解决此问题,请将演员表更改为
(NSString * const *)
,显然,必须使用const才能安抚ARC。
as cashBalanceKeyPath
is a pointer and context
is a pointer the correct way to compare this two is: 由于
cashBalanceKeyPath
是一个指针, context
是一个指针,比较这两者的正确方法是:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == (__bridge void *)(cashBalanceKeyPath)) {
}
}
and the call should be: 呼叫应该是:
[xxx addObserver:self forKeyPath:cashBalanceKeyPath options:0 context:(__bridge void *)(cashBalanceKeyPath)];
I wonder how your code could work with MRC. 我不知道您的代码如何与MRC一起使用。
The whole problem can probably be avoided by writing 整个问题可能可以通过写来避免
static int cashBalanceKeyPathContext = 0;
and using &cashBalanceKeyPathContext as the context. 并使用&cashBalanceKeyPathContext作为上下文。
The reason you're getting the error is because you're comparing a string and a pointer to a string, when you really just want to compare two strings. 出现错误的原因是,当您确实只想比较两个字符串时,您正在比较字符串和指向字符串的指针。 When you're comparing two strings, you should use
isEqualToString
. 比较两个字符串时,应使用
isEqualToString
。 So your code might look like this: 因此您的代码可能如下所示:
NSString *contextString = (__bridge NSString *)context;
if ([contextString isEqualToString:cashBalanceKeyPath])
{
//Do something
}
...
Hope this helps! 希望这可以帮助!
如果要比较字符串,则应使用isEqualToString方法:
对于字符串,ARC通常不喜欢__strong,并且Apple建议您使用copy。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.