Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I disable property auto-synthesis of properties in Xcode 5?

I have written a library to automatically generate NSUserDefaults accessors based on @dynamic properties that you declare in a 'preferences' class (see PAPreferences). You write the property in a .m file like this:

@property (nonatomic, assign) BOOL hasSeenIntro;

and then add this to the .h file:

@dynamic hasSeenIntro;

This works fine but if the user accidentally forgets to put in the @dynamic line, then the compiler will automatically generate an equivalent @synthesize line instead. There will be no warnings but of course my code won't be invoked for that property.

I'd like to know if there's a way to disable automatic property synthesis just for this class.

Update:

Thanks to Nikolai's answer, I remembered that it's possible to promote LLVM warnings to errors and wrapping the declaration with that error achieves the effect I was looking for (an error will be raised if the user forgets to specify the @dynamic line):

// Ensure we get an error if we forget to add @dynamic for each property
#pragma clang diagnostic push
#pragma clang diagnostic error "-Wobjc-missing-property-synthesis"

@interface Preferences : PAPreferences

@property (nonatomic, assign) BOOL hasSeenIntro;
@property (nonatomic, assign) NSInteger pressCount;

@end

#pragma clang diagnostic pop
like image 544
Denis Hennessy Avatar asked Mar 20 '23 18:03

Denis Hennessy


1 Answers

There's no way to do this via code.

There's a compiler warning (controlled via Xcode's build setting "Implicit Synthesized Properties", CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS) but you have to manually set this on the implementation file, so for your case that's not really helpful.

Here's another idea: Change your implementation to add the properties using a category on PAPreferences instead of a subclass. Then the compiler can't synthesize the accessors and will emit a warning if the @dynamic is missing.

@interface PAPreferences (SynthesizedProperties)
@property int foo;
@end

@implementation PAPreferences (SynthesizedProperties)
@end

Result:

> warning: property 'foo' requires method 'foo' to be defined - use @dynamic or provide a method implementation in this category

Additionally (or instead) you can introspect the property during runtime to detect accidentally synthesized accessors and emit a warning in this case.

like image 100
Nikolai Ruhe Avatar answered Apr 06 '23 07:04

Nikolai Ruhe