Instance Variables vs. Properties

Discussion in 'iOS Programming' started by ahan.tm, Oct 17, 2013.

  1. ahan.tm macrumors regular

    Joined:
    Jun 26, 2011
    Location:
    Florida
    #1
    Hi all,

    This is something that has always raised questions in my mind as I have seen many do it multiple ways.

    So, should all my variables be instance variables or properties. The NYTimes Obj-C Style Guide says to use properties, but then everything is accessible outside the class.

    I have various integers and booleans in my view controllers that SHOULD NOT be accessible outside the class. I was always just declaring them at the top of my implementation. They should be accessible by all methods in the class. Should they now be Ivars?

    Should my UI Elements(Buttons, etc.) be properties? I currently have them as properties.

    Thanks,
    ahan.tm
     
  2. Matthew Yohe macrumors 68020

    Joined:
    Oct 12, 2006
    #2
    You can create properties in your .m files too in what are called class extensions.

    Code:
    @interface Person ()
    @property NSObject *somethingElse;
    @end

    You can also use this trick to expose read only properties in the .h and redeclare them in the .m as readwrite:

    .h:

    Code:
    @interface Person : NSObject
    @property (nonatomic, readonly) NSObject *extraProperty;
    @end
    .m:

    Code:
    @interface Person ()
    @property (nonatomic, readwrite) NSObject *extraProperty;
    @end
    Here's Apple on the subject: https://developer.apple.com/library...s.html#//apple_ref/doc/uid/TP40011210-CH6-SW3


    Also, in reading the NYTimes guide, they mention this same method: https://github.com/NYTimes/objective-c-style-guide#private-properties
     
  3. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #3
    You should definitely use properties for variables that you want to expose to outside classes.

    As to what you do with private variables, its as much personal taste as anything.

    I tend to use instance variables for my private variables. I do this for 2 reasons: 1. I find the syntax a little cleaner. 2. Direct instance variables are slightly more efficient, since the compiler turns them into direct memory (or register) references, where properties always invoke a getter/setter method.

    Other people use properties for everything.

    Before the days of ARC, it made sense to use properties for all of your variables that contained objects, since the getters and setters took care of memory management for you. Now with ARC, that isn't needed any more.

    As the other poster said, it is possible to use a class extension, aka an anonymous category, to define private properties, instance variables, and methods in your classes. However, in Objective C nothing is really private. If the caller really wants to, they can subvert your privacy and access your internals anyway.
     
  4. Tander macrumors 6502a

    Tander

    Joined:
    Oct 21, 2011
    Location:
    Johannesburg, South Africa
    #4
    I've always use properties. Mainly because I like to do [self.propertyName] then I know that I've declared it in the class I am working with. I don't need to hunt it down and see what it is (NSArray, BOOL, etc)

    As Duncan says - personal taste really, I guess.

    Come compile and run time - I don't know if it makes that much of a difference.
     
  5. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #5

    I don't understand what you mean by
    If you use an instance variable it MUST be declared in the class in which you are working.

    Code:
    self.foo = 0;
    
    Code:
    foo = 0;
    
    The first line refers to a property of this object.

    The second refers to an instance variable (or possibly a local variable) of this object. It can't possibly refer to a variable from another object.
     
  6. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #6
    If there's something special you'll want to do with a private variable everytime you set or get it, then you should probably use properties that are defined in your file. Since you can't be certain that you won't want to do that later on, you should probably use properties now just so you don't have to refactor later.
     
  7. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #7
    What do you mean by "something special"?
     
  8. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #8
    To put it another way:

    If you have custom getters and/or setters on your properties that do something other than getting/setting the underlying instance variable, then you will need to use a property.

    As to the "Since you can't be certain that you won't want to do that later on, you should probably use properties now just so you don't have to refactor later" part, I disagree. This level of refactoring is trivial, and even more so with the refactor command in newer versions of Xcode.

    Properties do have a small but non-zero performance cost associated with them. For most things the overhead is not meaningful, but not for ALL things.

    I would not use properties to index into pixel data in a loop for example, or anything that handles thousands of data items in a a loop.

    I use properties when I need their benefits (clearly documented public interface for outside access, or custom getters/setters) and use instance variables otherwise.
     
  9. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #9
    Maybe it's a view with a property and every time that property is updated it needs to be redrawn.
     
  10. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #10
    And how will refactoring a private variable into a property help in this regard?
     
  11. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #11
    A custom setter would be perfect for this.
     
  12. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #12
    If you set the variable from multiple places in your code, you can use a setter which includes a setNeedsDisplay.
     
  13. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #13
    Centralized checking to see if some value is in range in either the setter or getter.
    Key value observing.
    Subclass override and actually change a completely different variable in some subclass.
    Category override and going off and doing something completely different (flash the view red whenever some counter variable is incremented, etc.)
    Sending notifications when the property is changed or even just accessed.
    Debug logging whenever the property is touched.
    Requesting a view redraw when some property inside them is changed.
    etc. etc.

    If none of the above, then accessing an instance variable is faster and results in less code (by a near microscopic amount in the typical case).
     
  14. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #14
    Have you actually checked that?

    In any event, on the list of things you should consider when writing your code, performance should generally go near the bottom. Readability and debuggability are far more important and far more likely to be relevant and useful attributes of your code than performance. If at some point you find your code isn't performing well, then at that point you should make whatever changes are necessary to bring it to the necessary level of performance.
     
  15. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #15
    Which is why so many applications these days are vastly bloated, slow, carbon polluting, battery draining pigs.

    Programmers ignore performance, customers pay (with zillions of man-years of wasted lifetimes). There's a story where Steve Jobs related this misguided idea to a form of murdering ones customers.

    There are problem domains where a sludge slow app is still too fast to notice on modern hardware. But one shouldn't just assume that at the start when painting your app into a slothful corner.
     
  16. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #16
    Steady lad. There is such a thing as premature optimization.

    You want to use good design and algorithms, and not over-optimize the implementation at first. Then once you have a working app, you do performance testing on it, identify the bottlenecks, improve those, and then repeat until the performance meets your goals.
     
  17. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #17
    You shouldn't ever paint yourself into any corner. With your code properly structured, it should be easy to identify the slow parts and optimize them as necessary.
     
  18. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #18
    There are two "should's" in the above quote which seems to have not been the path taken by a lot of software that ends being left big and slow (thus eating up the poor users memory and battery life) as the developer moves on to other projects.

    ----------

    And there is also way too much premature de-optimization, where apps are built on top of a slow architecture that can't be fixed (within budget), and end up being killed by a competitor who comes along and uses properly efficient algorithms and data structures from the start.
     
  19. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #19
    My programming style regarding @properties has changed in the last five years from suspicion to acceptance. In the early days I used ivars directly everywhere as that's how I learned to do it. Now I use properties everywhere unless there's some special reason not to.

    When I go into old code I usually update it to my more recent style, which also is based on the compiler's more modern features. So I remove ivar declarations, remove method prototypes in the class extension or if unneeded from the header file. My goal is to have a simple, short, easy to understand header file. Naturally I convert ivar usage to property usage.

    You would think that converting ivar usage to @properties is little more than a find and replace and probably in 75% of the cases that's all it is. However, I find that some ivar usages can't be simply converted to @properties. I think that in some of these cases I was doing something that was a little bad that I could get away with in the ivar case but cannot get away with in the property case. Any use of pointers to access ivars can't be replaced directly by @properties. Any case where the underlying ivar is really a different class than the declared property can't be simply replaced. I have some cases where there was a public property that was an immutable type while the actual ivar was a mutable type and all private accesses used the ivar. This isn't a very good thing to do.

    Anyway, I coming to the conclusion that using @properties rather than ivars is more likely to result in clean code.
     
  20. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #20
    In all but the simplest of projects, maintenance releases will be required. Newer technologies will come along and be incompatible with your code. Bugs have snuck past your QA and unit tests. You need to have code that is maintainable above all else.

    Within pragmatic programming, there is no such thing as "premature de-optimization". Nobody asks "How can I make my code slower?" (unless they're the same sort of person who enjoys esoteric languages.) Many people will ask, before they even know that it's necessary, "How can I make my code faster?" What's the point of asking such a question? How would you even know when it's as fast as it can get? You'd have to waste a large amount of time writing a considerable amount of proofs to be able to definitively say it's as fast as possible.

    The question they should ask is, "How can I make this code as easy to read and understand as possible?" Incidentally, that's also the code that is quickest to type (or at least in my experience it is.)

    You save time by writing it quickly, reading it quickly, and debugging it quickly, at the cost of having a small chance (<10%) that maybe it'll be too slow and will require some optimization later on.

    So it's most budget conscious to have a feature complete project as quickly as possible, and then to spend some budget at the end refining any slow parts that need it.
     
  21. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #21
    Unfortunately, these are often the same question (or have the same most obvious answers... whether you like it or not).

    Fact is that unmaintainable software does not have infinite cost, and it's easy for maintainable software to end up having hidden costs that are far far higher than one imagines (multiple man-years worth of human lives lost waiting for XYZ, etc.).
     
  22. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #22
    Except they don't have the same solution. I can write a sort method that performs worst than n^2. It's not the most legible solution. The most legible ones sort in n^2. There are less legible ones that perform in better than n^2.

    I wonder about that, though. These lost seconds are distributed amongst numerous different individuals at different times. What difference does it make whether they wait 0.1 second or 1 second? At some point, I'd imagine it's around 5 seconds, it's impossible for the user to do anything more productive than wait if they have less time.
     
  23. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #23
    That extra .9 seconds might kill user satisfaction.

    http://glinden.blogspot.com/2006/11/marissa-mayer-at-web-20.html
     
  24. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #24
    Okay, sorry. What difference does 0.01 and 0.1 seconds make? So long as we're not talking about things that demand real time response (IE, in a game or in a touch controlled interface,) the user won't notice.

    Ever since MacRumors had that video from Microsoft discussing touch delays, I've really noticed it.
     
  25. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #25
    If you are doing live audio, or a FPS game, an extra 100 milliseconds latency can take your guitar effects processing or fast 3D game from great to unusable. Even an extra 33 mS can be really bad.

    That said, using instance variables is only likely to make a difference inside an app's innermost loops that touch lots of data: image pixels, sim particles, vast polygon strips, audio samples, mining large data sets, etc.

    But some developers make apps that do just that type of processing. Why? Because such a small percentage developers know how to do that well, it gives the developers who have the chops, re performance, to differentiate their apps competitively.
     

Share This Page