在 @interface 内部还是外部声明 IBOutlet?

发布于 2024-10-10 16:42:39 字数 688 浏览 3 评论 0原文

抱歉,如果我对这个太挑剔了,但我现在正在学习 iOS 编程,我发现有些人像这样声明 IBOutlet :

IBOutlet 附加到属性

#import <UIKit/UIKit.h>
#import "CustomCell.h"

@interface CustomTableViewController : UITableViewController {
  CustomCell *customCell;
}
@property (nonatomic, retain) IBOutlet CustomCell *customCell;
@end

还有一些人这样声明:

IBOutlet 附加对于接口内部的声明,

#import <UIKit/UIKit.h>
#import "CustomCell.h"

@interface CustomTableViewController : UITableViewController {
  IBOutlet CustomCell *customCell;
}
@property (nonatomic, retain) CustomCell *customCell;
@end

哪一种是声明它的正确方法?它们之间有什么区别吗? 如果有人知道解释为什么他们把它放在不同的地方,那么学习就会很棒。

多谢 :)

sorry If am I being too picky on this one but I am learning iOS programming now and I've seem some people who declare the IBOutlet like this:

IBOutlet attached to property

#import <UIKit/UIKit.h>
#import "CustomCell.h"

@interface CustomTableViewController : UITableViewController {
  CustomCell *customCell;
}
@property (nonatomic, retain) IBOutlet CustomCell *customCell;
@end

And some declaring like this:

IBOutlet attached to the declaration inside the interface

#import <UIKit/UIKit.h>
#import "CustomCell.h"

@interface CustomTableViewController : UITableViewController {
  IBOutlet CustomCell *customCell;
}
@property (nonatomic, retain) CustomCell *customCell;
@end

which one is the proper way to declare it? Are any differences between them?
If someone know to explain why do they put it on different places it would be awesome to learn.

Thanks a lot :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一口甜 2024-10-17 16:42:40

这两个仍然是“界面内部”,所以你的标题有点令人困惑,但我明白你在问什么。

在许多情况下,这两种方法的结果是相同的,但又有所不同。 IBOutlet 属性将调用该属性的 setter 方法,如果设置该属性应该产生一些副作用,则该方法使您有机会覆盖该 setter。

我更喜欢在属性上使用出口,因为我认为这使得从 nib 加载的对象的内存管理更加清晰。看看 nib 对象的内存管理,我想你会明白我的意思。

nib 文件中的对象在创建时保留计数为 1,然后自动释放。当重建对象层次结构时,UIKit 使用 setValue:forKey: 重新建立对象之间的连接,它使用可用的 setter 方法,或者如果没有可用的 setter 方法,则默认保留对象。这意味着(假设您遵循“出口”中显示的模式)您拥有出口的任何对象仍然有效。但是,如果有任何顶级对象未存储在 Outlet 中,则必须保留 loadNibNamed:owner:options: 方法返回的数组或数组内的对象,以防止这些对象过早释放。

IBOutlet ivars 将调用这些 ivars(如果存在)的 setter,如果没有找到 setter,则直接保留从 nib 加载的对象。

将属性宣传为 IBOutlet 至少可以清楚地表明,该属性的 setter 将始终被使用,并遵循为该属性设置的任何内存管理规则。

最后,我认为 IBOutlet 是类的公共接口的一部分,因此最好公开方法(通过属性)来急切地使用它们,而不是使用 -setValue:forKey: 来操作支持 ivars,这应该是一个实现细节。

Both of those are still "inside the interface" so your title it a bit confusing but I see what you are asking.

In many cases the result of either approach will be the same but they are different. An IBOutlet property will call the property's setter method which gives you an opportunity to override that setter if setting that property should have some side effect.

I prefer to use outlets on properties because I think it makes the memory management of the objects loaded from the nib much clearer. Take a look at memory management of nib objects and I think you will see what I mean.

Objects in the nib file are created with a retain count of 1 and then autoreleased. As it rebuilds the object hierarchy, UIKit reestablishes connections between the objects using setValue:forKey:, which uses the available setter method or retains the object by default if no setter method is available. This means that (assuming you follow the pattern shown in “Outlets”) any object for which you have an outlet remains valid. If there are any top-level objects you do not store in outlets, however, you must retain either the array returned by the loadNibNamed:owner:options: method or the objects inside the array to prevent those objects from being released prematurely.

IBOutlet ivars will call setters for those ivars if they exists and directly retain the object loaded from the nib if no setter is found.

Advertising the property as the IBOutlet at least makes it clear that the property's setter will always be used and follow whatever memory management rule has been set for that property.

Finally I argue that IBOutlets are part of the public interface of a class and it is therefore better to expose methods (via a property) for working with them eager than using -setValue:forKey: to manipulate the backing ivars which should be an implementation detail.

后来的我们 2024-10-17 16:42:40

这两种样式是可以互换的,生成的代码或从笔尖加载对象的方式没有区别。真的。

然而,两种样式都有多余的线条。只需省略 ivar 声明即可。 仅仅一行

@property (nonatomic, retain) IBOutlet CustomCell *customCell;

在现代运行时,

就足够了。如果您有一个复杂的项目,我建议将所有出口从公共接口移至单独的头文件中。大多数插座都是私有接口,将它们放在标头中的唯一原因是 Interface Builder 可以找到它们。

The two styles are interchangeable, there is no difference in the generated code or the way objects will be loaded from a nib. Really.

However, both styles have a redundant line. Simply leave out the ivar declaration. Just the line

@property (nonatomic, retain) IBOutlet CustomCell *customCell;

is sufficient in the modern runtime.

If you have a complex project, I suggest moving all the outlets out of the public interface into a separate header file. Most outlets are private interface, the only reason to have them in a header is so Interface Builder can find them.

彼岸花似海 2024-10-17 16:42:40

两种方式都可以声明,实际上没有区别。

但是,事情是这样的:

如果你需要你的类有一些具有特殊行为的 ivar 或者它必须从外部访问等,并且它必须是一个属性,那么我会说您有 2 个选项可供选择(附加到属性和类接口内部)。

如果不是您的情况,请不要创建属性,这不是必需的,只需在类接口内执行即可。

希望它有帮助;)

You can declare both ways, there is no difference actually.

But, here is the thing:

If you need your class to have some ivar with a special behavior or it has to be accessed from outside, etc, and it has to be a property, then I will say you have 2 options to choose from (attached to the property and inside the class interface).

If that is not your case, don't create a property, is not necessary, just do it inside your class interface.

Hope it helps ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文