Xcode compilation error: synthesized property 'xxxxxx' must either be named the same as a compatible IV

Source: Internet
Author: User
Tags emit

---- 2011.07.21 update ----

// 2011.07.21 // Xcode 4.0.2// 64-bit    @interface IvarNameTest : NSObject {@private}   @property(nonatomic) NSNumber *number;@property(nonatomic) float f;   - (void)printValue;@end
#import "IvarNameTest.h"   @implementation IvarNameTest  @synthesize number = anyIdentifier;@synthesize f = anyIdentifier2;   - (void)printValue{    anyIdentifier = [NSNumber numberWithDouble:77.77];    anyIdentifier2 = 7.7f;    NSLog(@"%@, %f", anyIdentifier, anyIdentifier2);}@end

Note:

Compile on the 64-bit platform. If no instance is defined in the @ interface blockVariableThe @ property declaration is provided, and @ synthesize is provided in the @ implementation block.

Conclusion:

1) in the form of @ synthesize name, the variable name automatically created by the compiler is name, that is, the name in the @ property declaration;

2) if it is in the form of @ synthesize name = XXXX, the name of the instance variable automatically created by the compiler is XXXX.

---- 2011.07.21 update ----

The reason for investigating this error is not the error itself, but when I read Li Chen's iPad application development practices, I wrote an example in xcode 4.

A problem was found.

Class header file:

#import <UIKit/UIKit.h>  @class HelloWorldMailViewController; @interface HelloWorldMailAppDelegate : NSObject <UIApplicationDelegate> {} @property (nonatomic, retain) IBOutlet UIWindow *window;@property (nonatomic, retain) IBOutlet HelloWorldMailViewController *viewController; @end

Implementation file:

// ... @implementation HelloWorldMailAppDelegate  @synthesize window=_window;@synthesize viewController=_viewController;  // ... @end

There are two questions about the Code:

1) since there are @ property declarations and @ synthesize, why is there no ivars declaration in the @ interface of the class:

UIWindow *window;HelloWorldMailViewController *viewController; 

2) @ implementation:

@synthesize window=_window;@synthesize viewController=_viewController;

What does that mean?

For this reason, I wrote a similar code test and got the error message in the title (obtained during 32-bit compilation ). Google to this post:

Http://www.cocoabuilder.com/archive/cocoa/198573-property-problem.html

In the reply, the question is clearly explained:

In 32-bit, if the @ Interface part of the class is not declared as Ivar, but there is a @ property declaration, the @ implementation part of the class has a corresponding @ synthesize, the following compilation error is returned: synthesized property 'xx' must either be named the same as a compatible Ivar or must explicitly name an Ivar at 64-bit, at runtime, the system automatically adds Ivar to the class. The added Ivar is prefixed with an underscore. @ Synthesize window = _ window in the Declaration above indicates that the window attribute is the _ window instance variable synthesis accessors method.

Post in cocoachina: http://www.cocoachina.com/bbs/read.php? Tid-66688.html

Excerpt from the original post:

On 2/11/08, Randall Meadows <cocoa-dev...> wrote:> AFAICT, "capturing" IS the name of my ivar.  What is it *really*> complaining about?  What did I do wrong?You are incorrect.  Re-read the documentation closely; on 32-bitarchitectures (the "non-fragile instance variable runtime") you mustprovide an instance variable for your property.  If it does not havethe same name as the property, you must specify this in yourdeclaration.On 64-bit architectures, you can omit the ivar declaration.Also, you have not specified a memory management method in your@property declaration, which you must do if you are not using garbagecollection.HTH,--Kyle Sluder
> I've boiled the problem down to this snippet:> > @interface MyWindow : NSWindow> {> }> @property(readwrite) BOOL    capturing;...> error: synthesized property 'capturing' must either be named the> same as a compatible ivar or must explicitly name an ivarYou haven't declared a compatible ivar named "capturing". You'd needto do something like this:@interface MyWindow : NSWindow{BOOL capturing;  // <-- here!}@property(readwrite) BOOL    capturing;The line marked above declared an ivar with the same name and the sametype as your property declaration, so now synthesize will be able todo its thing.Obj-C *can* be smart enough to generate this ivar for you behind thescenes, but only if you're using the 64bit runtime. If you don'trequire 32bit compatibility, turn it off, and then you don't have toworry about declaring these ivars for synthesize.Cheers,-Joshua Emmons
FYI: The property name doesn't have to match the instance variablename, so it's OK to keep using prefixes on your ivar names. So youcould declare the class as@interface MyWindow : NSWindow {BOOL _capturing;  // or mCapturing or whatever}@property(readwrite) BOOL    capturing;@endand then in the implementation use@synthesize capturing=_capturing;I strongly recommend prefixing all instance variables, to avoidconfusion with locals. I've also found out the hard way that it's evenmore important to do this with properties.Not prefixing property instance vars can lead to a type of mistakewhere, in the implementation of the same class, you accidentally writesomething likecontents = [NSArray array];when you meant to writeself.contents = [NSArray array];Do you see the problem? Assuming no GC, and the 'contents' property ismarked 'retain' or 'copy', the first line will cause a crash sometimelater on, because you directly assigned an autoreleased value to aninstance variable, so sometime after this method leaves scope, thatarray is going to be dealloced and 'contents' will be a bad pointer.The second line invokes the property's setter method, which correctlyretains or copies the array.—JensPS: To forstall an FAQ: Yes, it is kosher to use "_" as your ivarprefix, even though the Foundation and AppKit classes do the same.Name collisions are not a problem. It is, however, recommended to notuse "_" as a method name prefix, because you can collide with andaccidentally override internal superclass methods.
>> PS: To forstall an FAQ: Yes, it is kosher to use "_" as your ivar>> prefix, even though the Foundation and AppKit classes do the same.>> Name collisions are not a problem.> > Could you elaborate?  If I subclass NSView and add an ivar named> "_sisterView" then in some future SDK NSView.h also gets a _sisterView> ivar, wouldn't there be a compiler error?Yes, and that's why I believe Jens is telling you that it's OK to usethe same prefix for ivars as anyone else that you're sharing codewith: Because any name clashes would be immediately apparent. This incontrast to, for example, method names.> Pity private ivars have to be in public headers...Agreed, that is truly a pity.j o a r
> Could you elaborate?  If I subclass NSView and add an ivar named> "_sisterView" then in some future SDK NSView.h also gets a _sisterView> ivar, wouldn't there be a compiler error?Yes, but not a runtime error, and it wouldn't break binarycompatibility. So it wouldn't affect users, only you (or other peopleusing your source code), and it's easy to fix with a quick Refactorcommand.Unlike a method-name conflict, which _would_ break existing binarycopies of your app, in strange and hard-to-predict ways.—Jens
> Yes, and that's why I believe Jens is telling you that it's OK to> use the same prefix for ivars as anyone else that you're sharing> code with: Because any name clashes would be immediately apparent.> This in contrast to, for example, method names.Note that this isn't true in the 64-bit runtime, where ivars don'thave to be declared publicly.  There, AFAIK, ivars are uniqued by namestill, so unexpected clashes are possible (and wouldn't be detected atcompile time, necessarily... someone less lazy than me should writesome test cases and find out   ).Wade
On Feb 17, 2008, at 12:03 PM, Sherm Pendley wrote:> Why would the parent's size be hard-coded? You can get the size of> the parent at run time, by dereferencing a couple of levels into> isa. All the compiler would have to do is emit code that walks down> isa to get the parent's size, and add it to self to establish a base> address. The only hard-coded offsets would then be relative to that> base, for the current class' own ivars.> > Changing the size of the parent class wouldn't break such a scheme,> so far as ordinary usage goes. People playing games with sizeof() or> @defs deserve whatever breakage they get.  > > Doesn't the current (I refuse to call it "legacy" quite yet...) 32-> bit compiler emit code like that when ivars are accessed?To dive a little deeper, consider the instance variables for NSView,including  inherited ivars.  Well, a subset, really:@interface NSObject <NSObject> {    Class    isa;}@interface NSResponder : NSObject <NSCoding>{    id _nextResponder;}@interface NSView : NSResponder{    NSRect              _frame;    NSRect              _bounds;    id                  _superview;    id            _subviews;    NSWindow            *_window;}Within the legacy runtime ;), the memory for NSView looks just like aC struct with this layout:struct NSViewLikeStruct {    Class    isa;    id _nextResponder;    NSRect              _frame;    NSRect              _bounds;    id                  _superview;    id            _subviews;    NSWindow            *_window;};So, in the implementation of an NSView, an access to an instancevariable -- say _subviews -- is compiled down to something equivalentto:((struct NSViewLikeStruct *) aView)->_subviewsNow, if an instance variable is added to NSObject or NSResponder andthe subclasses are not compiled, the above code will have the wrongoffset.This is fragile, but allows instances to be allocated as a singlechunk of memory while also reducing the amount of metadata and/orindirection required to get at any given instance variable's slot.To fix the issue, it has to be done partially at runtime and requiresa different layout for the instances...b.bum
On 17 Feb '08, at 12:03 PM, Sherm Pendley wrote:> Why would the parent's size be hard-coded? You can get the size of the> parent at run time, by dereferencing a couple of levels into isa.> All the> compiler would have to do is emit code that walks down isa to get the> parent's size, and add it to self to establish a base address. The> only> hard-coded offsets would then be relative to that base, for the> current> class' own ivars.This has been done before, most notably in IBM/Apple's "SOM" runtimethat was used in OpenDoc in the mid-'90s. The main drawback is that itbecomes more expensive to access instance variables. Instead ofindexing off a constant offset from the object pointer, you have tocall a runtime function that returns a pointer to the class's ivars,and index off that.It also adds some complexity to both the compiler and the runtime, todeal with the dynamic location of the ivars.The "Fragile Base Class" problem is common to many object runtimes. C++ has it even worse, in that the normal vtable-based runtime makes itimpossible to add even *methods* to a base class without breakingsubclasses. It turns out that fragile methods are much more of aproblem than fragile instance variables; it's fairly easy to reserve afew unused ivars in advance and use them later on. So Obj-C has beenable to work quite well in dynamic libraries, while C++ has usuallyfallen on its face. But it's nice that this last restriction is nowlifted in the 64-bit environment.(Scripting languages don't generally suffer from this. Most of themstore an object's ivars in a hashtable, which is much slower but muchmore flexible, so you can do crazy stuff like adding ivars toindividual instances.)—Jens

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.