简体   繁体   English

源文件中的Objective-C成员变量vs属性

[英]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. 我了解Object-C中成员变量和属性之间的区别,但是有一件事让我感到困惑。 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. 如图所示,memberStr和propertyStr无法从外部看到。 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. properyStr将自动生成getter和setter。

you can define custom setter for propertyStr as below. 您可以如下定义propertyStr自定义设置器。 When you use self.propertyStr , it will create a default object for you. 当您使用self.propertyStr ,它将为您创建一个默认对象。 It will be useful for initialising objects like NSMutableArray , NSMutableDictionary etc. 对于初始化诸如NSMutableArrayNSMutableDictionary等对象将很有用。

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

memberStr will not have these options. memberStr将没有这些选项。

I understand the difference between member variable and property in Object-C 我了解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. 编译器将编写适当的getters和(可选)setters,并将自行组织存储,除非您覆盖其中任何内容。

Both member variables and properties can be declared either in the @implementation or in the @interface . 成员变量和属性都可以在@implementation@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. 如果在@interface则可以由子类访问它。

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. 外部类可以使用键值编码机制,即使@property不可见。

Questions you may therefore be likely to ask: 因此,您可能会问的问题:

Q) Why would I put a member variable into the @interface ? 问)为什么要将成员变量放入@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. 但是,在过去,由于旧的Objective-C运行时的工作原理,必须将所有成员变量放入@interface 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 ? 问)为什么我要声明仅对@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. 但是,在过去,这是创建在@interface中不可见的成员变量的唯一方法,因此人们在短时间内处理大多数成员变量的方法也是如此。 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. 同样,您可以声明一些内容,比如说retain ,然后使用getter / setter并假设正在进行正确的内存管理,因此在引入ARC之前,它就充当了某种语法糖。 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. 一个面向对象编程的主要目的之一是有一堆离散的演员是说:“我可以做X”与它们究竟是如何做到这一点是别人的事。

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. memberStr的第一个是实例变量或ivar。

There is no need to have memberStr any more if you have a property setup for this all you need is. 如果您为此拥有一个属性设置,则不再需要memberStr

@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. 这样做的原因是,将与setter和getter方法一起为您自动创建ivar。

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. 与接口文件(.h)相比,在实现文件(.m)界面中声明属性的唯一区别是,该属性仅对此类是私有的。 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. 它们以这种方式使用的一件事是,当您拥有一个声明为public的只读属性,但仍希望该setter属于此类的范围时。 So you may have something like 所以你可能会有类似

.h 。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 .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. 在实现文件(.m)中具有该属性与在接口文件(.h)中具有该属性完全相同,它们将起作用并执行相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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