Implicit conversion of non-w480> void * pointer type to NSString * __ strong * is prohibited by ARC

I got the above error when porting to 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 the bridge:

 if (&cashBalanceKeyPath == (__bridge NSString *)context) 

I got an error: Comparison of distinct pointer types (NSString *__strong* and NSString *)

How can I do the conversion? Thank you in advance.

+6
source share
8 answers

I can’t say exactly why, but you don’t get warnings or errors if you change the comparison order:

 if (context == &cashBalanceKeyPath) { // ... } 
+2
source

It seems you are using the address of the variable as a unique tag, so there are no problems with memory / ownership management. To compare addresses, change the address of the variable to void:

 if ((void *)&cashBalanceKeyPath == context) 

It seems to give the compiler everything he needs without any bridge transfer.

+2
source

If you cross out the __strong message in the error message, it will clear what happens:

 Comparison of distinct pointer types (NSString ** and NSString *) 

&cashBalanceKeyPath is a pointer to an NSString or NSString** object, while the context is passed to NSString* or a regular NSString object (which is not the case).

So, to fix the problem, change the cast (NSString * const *) , apparently, const should calm the ARC.

+1
source

as cashBalanceKeyPath is a pointer, and context is a pointer, the correct way to compare which is as follows:

 - (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.

0
source

The whole problem can probably be avoided by writing

 static int cashBalanceKeyPathContext = 0; 

and using & cashBalanceKeyPathContext as the context.

0
source

The reason you get the error is because you are comparing a string and a pointer to a string when you really just want to compare two strings. When you compare two strings, you should use isEqualToString . So your code might look like this:

 NSString *contextString = (__bridge NSString *)context; if ([contextString isEqualToString:cashBalanceKeyPath]) { //Do something } ... 

Hope this helps!

-1
source

If you want to compare strings, you should use the isEqualToString method:

-1
source

ARC usually dislikes __strong when it comes to strings, and Apple recommends using a copy.

-1
source

Source: https://habr.com/ru/post/948577/


All Articles