0

I have been programming for the iOS platform for the last few years but mainly using swift. In the recent months though, I have been tasked with a project using Objective C, and while I like it and found it easy to learn, there are some questions mainly about variables that I still don't quite understand.

1) What is the difference between declaring an instance variable and a property? Since the compiler automatically creates an instance variable for every property, is there any real advantage besides being able to pass in some parameters like atomic, nonatomic, strong, weak, assign, etc?

2) What is the difference between declaring variables in the @implementation or properties @interface inside the .m file? From what I understand, declaring in the @implementation makes it a static variable and declaring it in the @interface makes it an instance variable, is that correct? Also why do classes that inherit from UIViewController (for example) already have an @interface in the .m file and classes that inherit from NSObject don't?

3) (Personal Question) Do you usually set a property to be atomic or nonatomic? I find that atomic is better because while it may be slower it is thread safe, but I see most people using nonatomic. Is the speed difference still noticeable nowadays with the amount of power we have?

4) Whenever I declare two instance variables with the same name in the @implementation in two different classes I get a "duplicate symbol" error. Why does this happen?

Just another simple question out of curiosity: I see many questions where in the code the @interface has curly braces, but in my code I've never seen it, rather it ends with a @end like the @implementation file. Was this in earlier versions of Obj-C or is there any real difference?

Thank you so much, I know these are 4 or 5 questions, but I jumped so quickly into a project and I think I really need to learn the basics, which I skipped because I could not find answers to this questions.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Mykod
  • 587
  • 1
  • 5
  • 16

2 Answers2

3

1) What is the difference between declaring an instance variable and a property? Since the compiler automatically creates an instance variable for every property, is there any real advantage besides being able to pass in some parameters like atomic, nonatomic, strong, weak, assign, etc?

A property may or may not be backed by an instance variable. By default they are but you can declare a property and the explicitly provide both a getter and setter (if not read-only). Then the property will not have an implicitly declared ivar. Properties make it easy to indicate whether it is atomic or not, whether it is read-only or not, and it lets you indicate the memory management (strong, weak, copy, assign). Properties also provide support for key-value observing.

If you want a simple variable used privately without the need for any of those features, then a direct ivar without a property is over so slightly more efficient.

See Is there a difference between an "instance variable" and a "property" in Objective-c? for more details.

2) What is the difference between declaring variables in the @implementation or properties @interface inside the .m file? From what I understand, declaring in the @implementation makes it a static variable and declaring it in the @interface makes it an instance variable, is that correct? Also why do classes that inherit from UIViewController (for example) already have an @interface in the .m file and classes that inherit from NSObject don't?

The private @interface Whatever () in the .m is known as the class extension. It's basically a special unnamed category. There is no difference between declaring ivars there or in the @implementation block.

Personally I use the class extension to privately conform to protocols and to declare private properties. I use the @implementation block to declare private ivars.

Variables in the @implementation block are normal instance variables if they are put in the curly braces.

@implementation {
    // ivars here
}

// variables here are globals. Same as before @implementation or after @end

// methods

@end

Without the curly braces those variables become globals.

See Difference between variables in interface Object() {} and @implementation Object @end and Difference Between Declaring a Variable Under @Implementation And @Interface Under .m file for more details.

3) (Personal Question) Do you usually set a property to be atomic or nonatomic? I find that atomic is better because while it may be slower it is thread safe, but I see most people using nonatomic. Is the speed difference still noticeable nowadays with the amount of power we have?

Atomic properties are not really thread safe. It just means the assignment is atomic and a read is atomic but it doesn't really mean thread safe in the broader sense.

See What's the difference between the atomic and nonatomic attributes? for a much more thorough discussion.

4) Whenever I declare two instance variables with the same name in the @implementation in two different classes I get a "duplicate symbol" error. Why does this happen?

See #2. You must not have your variables in the @implementation block curly braces. Put the variables where they belong and the problem goes away.

If you actually want the variable to be a file static, put it before the @implementation to make it clear that it isn't part of the class and prefix the variable declaration with static. Then if you happen to have two with the same name in different files, there won't be a duplication problem if they are static.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • That is an amazing answer. Thank you so much! I just have one more question...So the difference between a global variable and an iVar in Objective C is just that a global variable has the same lifecycle of the application and the iVar has the same lifecycle of the class it was declared on. Is that just it? Then why would I use a global variable? – Mykod Jun 11 '18 at 23:01
  • Found this very good answer about the difference between iVars and Global Variables if someone has the same question : https://discussions.apple.com/thread/4477921 I just don't understand what's the point then of having a global variable. – Mykod Jun 11 '18 at 23:08
  • Properties are not a requirement for strong or weak. – Steven Fisher Jun 13 '18 at 23:12
  • @StevenFisher No, they are not. Is that implied anywhere in my answer? ivars and other variables are strong by default and they can be declared weak if needed. – rmaddy Jun 13 '18 at 23:15
  • @rmaddy Fourth sentence says "[property] makes it easy to indicate the memory management." But maybe you were comparing to getters/setters and I missed the point there. :) – Steven Fisher Jun 15 '18 at 02:12
  • @StevenFisher OK. I was simply listing the attributes you can apply to a property. I don't mean to imply that ivars can't also be declared as strong or weak. – rmaddy Jun 15 '18 at 02:27
  • Sorry, I wasn't meaning to sound snippy there. Just trying to suggest an improvement. :) – Steven Fisher Jun 15 '18 at 03:28
1

1) What is the difference between declaring an instance variable and a property? Since the compiler automatically creates an instance variable for every property, is there any real advantage besides being able to pass in some parameters like atomic, nonatomic, strong, weak, assign, etc?

Properties are really just methods wrapped in a syntax. They're intended to be called by other classes, assuming they're publicly provided. Instance variable is more like a field access in C. You should probably default to using properties (they support KVO, are safe on nil, etc.). You should certainly default to using properties for getting/setting, except possibly in the initializer.

Note, though, that the compiler does not always create instance variables. If you provide both getter and setter, you'll need to tell it to with @synthesize foo=_foo;.

2) What is the difference between declaring variables in the @implementation or @interface inside the .m file? From what I understand, declaring in the @implementation makes it a static variable and declaring it in the @interface makes it an instance variable, is that correct? Also why do classes that inherit from UIViewController (for example) already have an @interface in the .m file and classes that inherit from NSObject don't?

Historically, instance variables could only be defined in the @interface.

3) (Personal Question) Do you usually set a property to be atomic or nonatomic? I find that atomic is better because while it may be slower it is thread safe, but I see most people using nonatomic. Is the speed difference still noticeable nowadays with the amount of power we have?

The reason for using nonatomic is that atomic doesn't really solve thread safety as much as you'd think. For example, this is still thread unsafe, even if the property is set to atomic (since the value of foo could change between the read and write):

self.foo = self.foo + 1;

For this reason I think most favor nonatomic and handling thread safety specifically when needed.

Steven Fisher
  • 44,462
  • 20
  • 138
  • 192