#typedef and KVC in ObjC

I have a class that looks like this:

@interface Properties : NSObject { @private NSNumber* prop1; NSNumberBool* prop2; //etc 

where NSNumberBool is typedef:

 // in MyApp_Prefix.pch typedef NSNumber NSNumberBool; 

I have all the necessary @property and @synthesize declarations to create prop1 and prop2 properties.

Everything compiled and worked fine until I tried to access prop2 using [myProperties valueForKey: @ "prop2"]. This gives me the error "class is not key-value compliant". However, many of these calls work fine:

 myProperties.prop2; //works [myProperties prop2]; //works [myProperties valueForKey:@"prop1"]; //works [myProperties valueForKey:@"prop2"] // throws NSUnknownKeyException ?? 

What is going on here and how can I fix it?

Thanks,

+6
objective-c typedef key-value-coding
source share
4 answers

This is a pretty old post, but I came to it looking for a solution to this problem that is well resolved by Objective-C 2.0 @compatibility_alias . This allows you to write:

 @compatibility_alias NSNumber NSNumberBool; 

and create an alias created for NSNumber . KVO works great with it.

In accordance with the currently accepted answer, this is of great importance for the safe type.

+1
source share

From compiling your example and issuing class-dump , it appears on it that typedef turns into

 struct NSNumber { Class _field1; }; @interface Properties : NSObject { NSNumber *prop1; struct NSNumber *prop2; } 

Changing typedef to this seems to work fine, although it may not be exactly what you want.

 #define NSNumberBool NSNumber 
+4
source share

I suspect this is a problem with the way typedef interacts with the encoding method.

I believe that typedef remains the pure C keyword, and actually only happens with Objective-C "types, usually because they are implemented as structures.

As a result, when you enter NSNumber in NSNumberBool, it is great for method calls (and the syntax properties of points), but (assuming my theory is correct) it interrupts the encoding, which cannot say that NSNumberBool and NSNumber are the same same type.

I will be interested to know what someone who knows better says.

+4
source share

Like nall answer, I also tried a dump class. I found an interesting if ugly workaround. The following code:

 typedef NSNumber* NSNumberBoolPtr; @interface Test : NSObject { NSNumber *real; NSNumberBoolPtr poser; } 

dump class:

 @interface Test : NSObject { NSNumber *real; NSNumber *poser; } @end 

Again, not exactly what you want, but you would get a compiler time check when there was no interweaving of NSNumbers and NSNumberBools (which I assume is the reason for typedef in the first place).

+1
source share

All Articles