Problem
I've come across an interesting issue and wasn't able to find any documentation on it... Sometimes properties
declared in a protocol
are not implemented in a particular class conforming to that protocol
and a runtime exception occurs. Are dynamic property
definitions optimized away under some strange circumstance? Can protocols
not be used with properties
that were made to be declared dynamic
? Any insight into this would be greatly appreciated.
Below are some more details.
Given a protocol
:
@protocol MyProtocol <NSObject>
@property (nonatomic, strong) id someProperty;
@end
and a class implementing the protocol
like so:
@interface MyClass <MyProtocol>
@end
@implementation MyClass
@dynamic someProperty;
@end
I've noticed that sometimes I am unable to get any information from calling
class_getProperty(myClass, propertyName);
for the properties
in the protocol
. This only happens to some classes and seems to be sporadic.
I'm running the latest Xcode 4 and linking against the iOS 6 SDK. I do have the pre-release Xcode 5 installed on the same machine though it is not the default (via xcode-select).
Example
If you run this code:
@protocol MyProtocol <NSObject>
@property (nonatomic, strong) id someData;
@end
@interface MyObject : NSObject <MyProtocol>
@end
@implementation MyObject
@dynamic someData;
@end
and then you run
const char *name = [@"someData" UTF8String];
objc_property_t property = class_getProperty([MyObject class], name);
const char *attributes = property_getAttributes(property);
You WILL get meta data on the property
EVEN THOUGH the property
doesn't exist. In other words you don't need to synthesize the property to get it's attributes. The runtime still knows about it. Try it for yourself. The problem is that sometimes this doesn't happen. I want to know the conditions that cause the runtime to be unaware of the property
attributes.
Temporary Fix
My temporary fix is to just copy all the property
definitions in the protocol
and paste them into the .h file:
@interface MyClass <MyProtocol>
@property (nonatomic, strong) id someProperty;
@end
@implementation MyClass
@dynamic someProperty;
@end
This runs fine, though it is far from ideal. However, it suggests that my code is working correctly and the issue lies elsewhere.
I'd be happy to provide more details or background if needed.