2

I am following the tutorial here: http://blog.soff.es/archiving-objective-c-objects-with-nscoding to create an NSObject that can save my match data in a turn based game.

However I get this warning in my .m file:

Autosynthesized property 'title' will use synthesized instance variable '_title', not existing instance variable 'title'

So my Qustion is if (in the code below) I delete the code in between the brackets will I be losing something important?

 @interface Note : NSObject <NSCoding> {
  NSString *title;
  NSString *author;
  BOOL published; 
 }

 @property (nonatomic, copy) NSString *title;
 @property (nonatomic, copy) NSString *author;
 @property (nonatomic) BOOL published;

 @end
Sooc
  • 141
  • 7
  • as far as i know, nothing wrong happens as long as you take care of them appropriately. – Teja Nandamuri Aug 18 '15 at 18:49
  • if you need to access getter and setter methods of title, you need to use @prop *title. – Teja Nandamuri Aug 18 '15 at 18:51
  • Yes. This is redundant. You are following a really old tutorial and back then, this was considered the way to code. Now ivars and properties have distinct uses. See http://stackoverflow.com/questions/843632/is-there-a-difference-between-an-instance-variable-and-a-property-in-objecti – Dan Loughney Aug 18 '15 at 18:59
  • It's not redundant, it's a major trap that can cause you an enormous amount of headaches. This code creates for example a property title with a matching instance variable _title, PLUS a completely unrelated instance variable named title. So self.title = @"this"; and title = @"that" set two different instance variables. – gnasher729 Aug 18 '15 at 19:37

3 Answers3

4

You shouldn't explicitly declare ivars since the properties will auto-synthesize their own ivars with slightly different names. The explicit ivars are pointless and won't be used by the properties. Having them is just going to lead to bugs when you use your ivars by mistake when you meant to set a property.

The warning is pointing this out by letting you know there will be two similar ivars.

Your code should simply be:

 @interface Note : NSObject <NSCoding>

 @property (nonatomic, copy) NSString *title;
 @property (nonatomic, copy) NSString *author;
 @property (nonatomic) BOOL published;

 @end

This avoid bugs such as:

title = @"Some Title"; // sets your ivar, not the property

as opposed to:

_title = @"Some Title"; // directly sets the property's ivar

Of course you should use the property:

self.title = @"Some Title"; // uses the property methods
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Autosynthesize uses declared ivars, if it finds one with a fitting name. Beside this there are reasons for declaring ivars. – Amin Negm-Awad Aug 18 '15 at 18:58
  • @AminNegm-Awad Yes, declaring ivars is fine in of itself. But you shouldn't declare ivars for properties. Only declare ivars for variables not based on a property. – rmaddy Aug 18 '15 at 18:59
  • @AminNegm-Awad Why the the down vote? As the warning states, the property will synthesize the ivar with an underscore. The properties will *not* use the explicitly declared ivars unless you add `@synthesize title`, for example. – rmaddy Aug 18 '15 at 19:00
  • 1. I always talked about ivars for properties. An use case is to have a mutable subclass internally. The synthesize will give you the immutable base class. 2. Downvote for "You shouldn't explicitly declare ivars since the properties will auto-synthesize their own ivars" This is not correct. – Amin Negm-Awad Aug 18 '15 at 19:03
  • @rmaddy thanks for the answer. As a follow up question how do I send the data in this object? – Sooc Aug 18 '15 at 19:07
  • @AminNegm-Awad It is correct. The single line `@property foo` automatically synthesizes the ivar `_foo`. There is *no* need to explicitly declare the ivar or use `@synthesize`. That was true years ago but not any more. Your understanding seems to be out of date. – rmaddy Aug 18 '15 at 19:07
  • @Sooc That's a completely separate question. I suggest posting another question if needed. – rmaddy Aug 18 '15 at 19:07
  • What is not true is the part "You shouldn't explicitly declare ivars **since the properties will auto-synthesize their own ivars**". They won't, if the ivar has the identifier underscore+propertyidentifier. So the statement is simply wrong. For years. From the very beginning of autosynthesize. – Amin Negm-Awad Aug 18 '15 at 19:12
  • Beside that it is simply wrong that one should not declare ivars for properties. There are reasons for it as I said. – Amin Negm-Awad Aug 18 '15 at 19:12
  • @AminNegm-Awad OK, now you're changing the question. The OP didn't declare ivars with an underscore. So the compiler does auto synthesize ivars for the properties (with an underscore in the name). This is not wrong. Now, if the OP had declared the ivars with the underscore in the name, then yes, the properties would use those explicit ivars since the name is the same as what would have been synthesized. But that's not the case here. Perhaps it would help if you gave a good reason for why someone should explicitly declare ivars for a property instead of simply using the implicit ones. – rmaddy Aug 18 '15 at 19:17
  • 1. No, your answer do not mention that limitation. It is simply: "You shouldn't explicitly declare ivars since the properties will auto-synthesize their own ivars". This is a general rule. 2. I gave you an example in my second comment. – Amin Negm-Awad Aug 18 '15 at 19:19
0

You would be losing instance variables, but you don't really want them as the properties will create them for you (with slightly different names) and it's safer to access these (kind of hidden) auto-generated instance variables via the property accessor methods.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Wain
  • 118,658
  • 15
  • 128
  • 151
0

Yes it is and likely you get something you do not want.

If you do not have an instance variable neither with the identifier identifier nor with the identifier _identifier, manual synthesize and automatic synthesize will create one with the name _identifier.

If you already have an instance variable with the identifier _identifier, manual synthesize and automatic synthesize will use it. (Therefore in most cases it is meaningless to declare such an instance variable.)

But if you have an instance variable with the identifier identifier (without underscore) manual synthesize will use it, while automatic synthesize will not use it and instead create a new one with the identifier _identifier. Therefore you have two instance variables identifier and _identifier. Typically you do not want this.

Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50