When to use instance variables and when to use pro

2019-01-22 16:12发布

问题:

When using Objective-C properties can you stop creating instance variables altogether or do explicit instance variables (not the ones synthesized by the properties) still serve a purpose where properties would be inappropriate?

回答1:

can you stop creating instance variables altogether

No, you can't (in a sense). What you can do is stop declaring them if you have properties. If you synthesize a property and you haven't declared the instvar, it will get declared for you, so you are creating an instance variable, just not explicitly.

do they still serve a purpose where properties would be inappropriate?

It used to be the advice to create properties for everything because having synthesized properties does almost all of the retains and releases for you. However, with ARC that reason for using properties to wrap the memory management has gone away. The advice now (for ARC) is, I believe, use properties to declare your external interface, but use direct instance variables where the variable is part of the object's internal state.

That's a good reason to adopt ARC: properties revert to their true purpose only of being part of the class's API and it's no longer necessary to use them as a hacky way to hide memory management work.

Edit

One more thing: you can now declare instance variables in the @implementation so there is now no need to leak any implementation details in the @interface. i.e.

@implementation MyClass
{
    NSString* myString;
}
// method definitions
@end

And I'm pretty sure it works in categories too. - see comment below



回答2:

I recommend declaring everything as properties and avoiding manual ivars altogether. There is no real upside to manually creating ivars. Declare public properties in your header @interface, declare private properties in a private class extension in your .m file.

To some of JeremyP's points, internal use of accessors still has significant value under ARC, even though memory management is no longer a significant concern. It ensures that KVO works properly, subclasses better, supports custom setters (particularly for things like NSTimer), supports custom getters (such as for lazy instantiation), etc. It is exceedingly error-prone to have a mix of accessors and ivars. It's far too easy to forget which you need to access in which way. Consistency is the hallmark of good ObjC.

If you absolutely must declare an ivar for some reason, then you should do it in the @implementation block as JeremyP notes.


UPDATE (Oct-2013):

Apple's guidance (From Programming with Objective-C: Encapsulating Data):

Most Properties Are Backed by Instance Variables

In general, you should use accessor methods or dot syntax for property access even if you’re accessing an object’s properties from within its own implementation, in which case you should use self:

...

The exception to this rule is when writing initialization, deallocation or custom accessor methods, as described later in this section.



回答3:

This question was addressed before here

When you use synthesize the instance variables are handled and instantiated for you. If you're using Lion with the new version of XCode also take a look at the various properties in ARC in Transitioning to ARC



回答4:

you can always access properties from outside. So if you want a variable only to be read from inside a class you still have to declare a iVar. Also accessing a public ivar with object->ivar is slightly faster than using a method-call.