简体   繁体   中英

Objective-C member variable vs property in source file

I understand the difference between member variable and property in Object-C, but there is one thing make me confused. See the following code.

test.h

@interface test : NSObject

@end 

test.m

@interface test()
{
  NSString *memberStr;
}
@property (nonatomic, strong) NSString *properyStr;
@end

As showed, the memberStr and propertyStr can't be see by outside. I want to know what is the difference between them. Because I don't how to chose the solution when i want to use local variable. Thanks!

properyStr will have the getters and setters generated automatically.

you can define custom setter for propertyStr as below. When you use self.propertyStr , it will create a default object for you. It will be useful for initialising objects like NSMutableArray , NSMutableDictionary etc.

- (NSString *)properyStr
{
     if(_propertyStr == nil)
     {
          _propertyStr = @"";
     }
     return _propertyStr;
}

memberStr will not have these options.

I understand the difference between member variable and property in Object-C

I'm not sure that you do.

A member variable is a variable that's visible only within the scope of instance methods.

A property is some attribute of the class that can be set or get. The compiler will write appropriate getters and, optionally, setters, and will organise storage for itself, unless you override any of those things.

Both member variables and properties can be declared either in the @implementation or in the @interface .

A member variable can never be accessed directly by unrelated classes, regardless of where it was declared. If it's in the @interface then it can be accessed by subclasses.

A property can always be read and, optionally, written by any other class, regardless of where it was declared. External classes can use the key-value coding mechanism even if the @property isn't visible to them.

Questions you may therefore be likely to ask:

Q) Why would I put a member variable into the @interface ?

A) It's unlikely you would. It will expose it to subclasses but usually wanting to do so is a design flaw. However, in olden times you had to put all member variables into the @interface for reasons of how the old Objective-C runtime worked. So older code and stuck-in-their-ways programmers will still sometimes follow this pattern.

Q) Why would I declare a property visible only to the @implementation ?

A) It's unlikely you would. However in olden times this was the only way to create member variables that weren't visible in the @interface so was the way people did most member variables for a brief period. Similarly, you could declare something, say retain , then use the getter/setter and assume correct memory management was going on, so it acted as some syntactic sugar in the days before ARC was introduced. As with the previous answer, there are therefore some people who still do so through habit and some code that still does so on account of being older. It's not something you'd often do nowadays.

EDIT: a better summary: properties adjust your class interface . Member variables adjust its implementation . In object-oriented programming you should be thinking of the two things as entirely disjoint .

One of the main purposes of object-oriented programming is to have a bunch of discrete actors that say "I can do X" with exactly how they do it being nobody else's business.

A property says what a class can do. A member variable is for the benefit of how the class does it.

Semantically they're completely separate issues.

First of memberStr is an instance variable or ivar.

There is no need to have memberStr any more if you have a property setup for this all you need is.

@interface test()
@property (nonatomic, strong) NSString *properyStr;
@end

The reason for this is that the ivar will be automatically created for you along side the setter and getter methods.

The only difference between declaring the property in the implementation files (.m) interface over the interface file (.h) is that it will be private to this class only. There are many advantages for having this such as maybe you don't want anything outside of the class to know about it but you want the property to be in scope for this class still. One thing that they are used for in this manner is when you have a readonly property declared public but you still want the setter to be in scope for this class. So you may have something like

.h

@interface MyObject : NSObject

// Other classes can see this property as it is public however they can only see
// it's getter and not the setter
@property (nonatomic, readonly) NSString *firstName;

@end

.m

@interface MyObject()

// But we still want to use the setter for this class only.
@property (nonatomic, strong) NSString *firstName;

@end

Otherwise except for being private to that class only; having the property in the implementation file (.m) will be the exact same as having it in the interface file (.h) they will act and do the same thing.

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