简体   繁体   中英

Objective C: I need some advice regarding properties vs ivars

I looked up my current problem on stackoverflow and many other website outlets, but I am a little confused to be quite honest. Should I only use properties when another class needs access to it and ivars when it is being used for only my private class? This is what I am getting so far, although I did hear some other things about when to use ivars and properties. I am just trying to keep my code clean and more modern. Any clarification will be appreciated.

This is a very opinion based topic. So I'm trying to stay with uncontroversial facts and advice:

  • Never access ivars from outside of the class. Public access would always be done through properties and their accessors or other methods. Nowadays headers should never contain ivar declarations.
  • Using ivars internally is possible and not uncommon. ARC makes this easy for object types, as ownership is handled automatically.
  • Using properties gives you proper ownership handling for NSString , NSArray et al. ( copy ).
  • Also, in some cases they can help with thread safety ( atomic ).
  • Using properties internally could make KVO compliance or other side effects easier to implement.
  • Using private properties is the standard pattern for exposing IBOutlets.
  • Properties can be queried during runtime. This is seldom needed, though.
  • Private properties have the problem of polluting the method namespace for a class. Unintentional overrides can occur.

The actual decision whether or not to use ivars in the implementation is a matter of personal preference. It is affected by many subtle details from code style.

In my opinion - you should only use properties, which are backed by an ivar if you didn't override the getter and the setter.

You should declare them in the public interface to make them public, and declare them in the private interface, that's right, to make them private.

There are many advantages to this, some are:

  1. Perform lazy instantiation in the getter
  2. Do validation in the setter
  3. Make a property readonly public and readwrite privately

Within your class, you should almost always access your properties through the getter/setter unless:

  1. You want to avoid the behavior you implemented in these methods (lazy instantiation, validation)
  2. You are in the initializer
  3. You are in the getter/setter

Here's an example of how of some of the following points:

@interface SomeObject : NSObject
@property (strong, nonatomic) NSMutableArray * objects;
@property (readonly, nonatomic, getter=isActive) BOOL active; // Public read-only 
@end

@interface SomeObject()
@property (readwrite, nonatomic, getter=isActive) BOOL active; // Can be updated internally
@property (nonatomic, getter=isVisible) BOOL visible;
@end

@implementation SomeObject

- (NSMutableArray)objects {
   if (!_objects) {
      _objects = [NSMutableArray array]; // Lazy instantiate when first accessed
   }
   return _objects;
}

- (BOOL)isActive {
   return _isActive && self.isVisible; // Cannot be active if not visible
}

- (BOOL)setActive:(BOOL)active {
   self.visible = active; // Keep visibility same as active
   _active = active;
}

-(BOO)setVisible:(BOOL)visible {
   _visible = visible;
   // perform animation or something else...
}

@end

Any of this cannot be achieved using ivars.

You should use declared properties inside and outside your class. Most developers say that you should only set the ivar behind a property in initializers. (I do not agree and use setters and getters in this case, too, but I'm in minority.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM