简体   繁体   English

ARC不允许将非Object-C指针类型void *隐式转换为NSString * __ strong *

[英]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**的指针,而上下文则被&cashBalanceKeyPathNSString*或普通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.

相关问题 ARC不允许将非目标C指针类型&#39;int *&#39;隐式转换为&#39;Bird *&#39; - Implicit conversion of a non-Objective-C pointer type 'int *' to 'Bird *' is disallowed with ARC TPMultiLayoutViewController的ARC转换; ARC不允许将Objective-C指针隐式转换为“ const void *” - ARC conversion of TPMultiLayoutViewController; Implicit conversion of an Objective-C pointer to 'const void *' is disallowed with ARC ARC禁止将非目标C指针类型&#39;const UInt8 *&#39;(aka&#39;const unsigned char *&#39;)强制转换为&#39;NSData *&#39; - Cast of a non-Objective-C pointer type 'const UInt8 *' (aka 'const unsigned char *') to 'NSData *' is disallowed with ARC 使用ARC-sqlite3不允许将Objective-C指针隐式转换为'void *' - implicit conversion of an Objective-C pointer to 'void *' is disallowed with ARC - sqlite3 从Objective-C指针到int *的隐式转换不允许使用ARC - Implicit Conversion from Objective-C Pointer to int * is Disallowed With ARC 禁止使用arc将ios的间接指针隐式转换为目标c的id指针 - ios implicit conversion of an indirect pointer to an objective c pointer to id is disallowed with arc 错误:在NSTimer选择器中,ARC无法将Objective-C指针隐式转换为&#39;SEL _Nonnull&#39; - Error : Implicit conversion of an Objective-C pointer to 'SEL _Nonnull' is disallowed with ARC in Selector Of NSTimer 在目标C中进行比较 - ARC不允许将&#39;int&#39;隐式转换为&#39;id&#39; - Comparing in objective C - Implicit conversion of 'int' to 'id' is disallowed with ARC 使用ARC隐式转换指向objective-c指针的间接指针 - implicit conversion of an indirect pointer to an objective-c pointer with ARC 目标C指针类型nsstring隐式转换为指针类型&#39;CFTypeRef&#39; - implicit conversion of objective-c pointer type nsstring to cpointer type 'CFTypeRef'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM