简体   繁体   English

IBOutlets应该是ivars还是属性?

[英]Should IBOutlets be ivars or properties?

Though I'm sure they exists, I'm having difficulties finding or pinning down an official best practice for declaring outlets in a ViewController. 虽然我确信它们存在,但我很难找到或确定在ViewController中声明出口的官方最佳实践。

There are 3 options so far as I can see: 到目前为止,我可以看到3个选项:

  1. ivar only 仅限ivar
  2. property only 仅限物业
  3. property backed with an ivar 以伊瓦尔为背景的财产

Xcode currently crashes when I try and auto-generate a property by dragging into my ViewController from IB, but from what I remember, doing so creates a property without an ivar. 当我尝试通过从IB拖入我的ViewController来自动生成属性时Xcode当前崩溃,但是从我记忆中,这样做会创建一个没有ivar的属性。 It is also possible to drag into the ivar section and this will create an ivar without a property. 也可以拖入ivar部分,这将创建一个没有属性的ivar。 This suggests that property-only and ivar only outlets are both OK with apple. 这表明,仅限房产和仅使用ivar的商店对苹果都是好的。

So in viewDidUnload we need to assign nil to any of our outlets, but what about dealloc. 所以在viewDidUnload中我们需要为任何一个出口分配nil,但是dealloc呢。 If we have used a property without an ivar, how can we release our outlet give that we are not supposed to use any accessors in an init or dealloc? 如果我们使用没有ivar的属性,我们如何释放我们的插座,我们不应该在init或dealloc中使用任何访问器?

It seems to me that the only pattern which would allow us to release our outlet without an accessor is using a property backed with an ivar, so we can manually release our ivar in dealloc without using its accessor, however this is the one option which Apple's code-generation doesn't support. 在我看来,唯一允许我们在没有访问器的情况下释放我们的插座的模式是使用支持ivar的属性,因此我们可以在dealloc中手动释放我们的ivar而不使用其访问器,但是这是Apple的一个选项。代码生成不支持。

As a rule of thumb, I usually create accessors for IBOutlet s. 根据经验,我通常会为IBOutlet创建访问器。

In ARC or non-ARC projects I usually do the following: 在ARC或非ARC项目中,我通常会执行以下操作:

//.h (ARC)
@property (nonatomic, weak) IBOutlet UILabel* myLabel;

//.h (non-ARC)
@property (nonatomic, retain) IBOutlet UILabel* myLabel;

//.m
@synthesize myLabel;

In this manner you can let the compiler to create an instance variable for you. 通过这种方式,您可以让编译器为您创建实例变量。 But you can also declare your instance variable and tell the compiler to use that. 但是您也可以声明您的实例变量并告诉编译器使用它。

Then you can use that accessors/instance variable wherever you want. 然后,您可以在任何位置使用该访问器/实例变量。

The Apple Memory Management guide says that you have to avoid accessors methods in init or dealloc methods when you have non-ARC projects. Apple内存管理指南说,当您有非ARC项目时,必须避免使用initdealloc方法中的访问器方法。 So, for example: 所以,例如:

// (non-ARC)
- (void)dealloc
{
   [myLabel release]; myLabel = nil; // I'm using the instance variable here!
   [super dealloc];       
}

This is very important in non-ARC projects. 这在非ARC项目中非常重要。 The reason is that, if there is no accessor, KVC will assign the nib object to the instance variable and will put a retain on it. 原因是,如果没有访问器,KVC会将nib对象分配给实例变量,并对其进行保留。 If you forget to release it, you could have a memory leak. 如果您忘记释放它,可能会发生内存泄漏。 Using an accessor force you to release that object at the end. 使用访问器强制您最后释放该对象。

I strongly suggest to read friday-qa-2012-04-13-nib-memory-management by Mike Ash. 我强烈建议阅读迈克·艾什(Mike Ash) 周五-Qa-2012-04-13-nib-memory-management It's a very cool article on nib and memory management. 这是关于笔尖和内存管理的非常酷的文章。

Hope it helps. 希望能帮助到你。

Here's my understanding 这是我的理解

Use properties for variables that will be accessed by other classes, either read from (getters) or written to (setters). 使用将由其他类访问的变量的属性,从(getters)读取或写入(setter)。 Both setters and getters are synthesized for properties. 两个setter和getter都是为了属性而合成的。

Use ivars for variables that will be used internally by the owning class only, that is, other classes will not set or get their values. 将ivars用于仅由拥有类在内部使用的变量,也就是说,其他类不会设置或获取其值。

Sure you can use properties in lieu of ivars, but they incur the function-call overhead whenever they're accessed. 当然,您可以使用属性代替ivars,但只要访问它们就会产生函数调用开销。 So if you have an internal variable that is accessed by your class a LOT, the function calls will affect the real-time performance, and this can be avoided by declaring them as ivars. 因此,如果您的类有一个内部变量很多,那么函数调用将影响实时性能,这可以通过将它们声明为ivars来避免。

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

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