如果我不保留 IBOutlet 会怎样?

2024-05-05

如果我这样做:

@interface RegisterController : UIViewController <UITextFieldDelegate>
{
    IBOutlet UITextField *usernameField;
}

而不是这个:

@interface RegisterController : UIViewController <UITextFieldDelegate>
{
    UITextField *usernameField;
}
@property (nonatomic, retain) IBOutlet UITextField *usernameField;

会不会有什么不好的事情发生?我知道在第二种情况下,该字段被保留,但这是否会有所不同,因为笔尖拥有该字段?如果没有保留,该字段会消失吗?在什么情况下?第一种情况下的代码有效,想知道这在内存管理方面是否是一个问题。


为了清晰和一致性,建议您声明所有 IBOutlet 的属性。 详细信息已在内存管理编程指南 http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmNibObjects.html。基本要点是,当您的 NIB 对象取消归档时,nib 加载代码将使用 setValue:forKey: 遍历并设置所有 IBOutlet。当您在属性上声明内存管理行为时,发生的事情并不神秘。如果视图被卸载,但您使用了声明为保留的属性,您仍然拥有对文本字段的有效引用。

也许一个更具体的例子有助于说明为什么应该使用保留属性:

我将对您正在工作的上下文做出一些假设 - 我假设上面的 UITextField 是由 UIViewController 控制的另一个视图的子视图。我假设在某个时刻,视图离开屏幕(可能它在 UINavigationController 的上下文中使用),并且在某个时刻您的应用程序会收到内存警告。

假设您的 UIViewController 子类需要访问其视图才能将其显示在屏幕上。 此时,nib 文件将被加载,并且每个 IBOutlet 属性将由 nib 加载代码使用 setValue:forKey: 设置。这里需要注意的重要事项是将设置为 UIViewController 的 view 属性的顶级视图(它将保留此顶级视图)和您的 UITextField,它也将被保留。如果只是简单地设置它,则 nib 加载代码将在其上保留它,否则该属性将保留它。 UITextField 也将是顶级 UIView 的子视图,因此它将有一个额外的保留,位于顶级视图的子视图数组中,因此此时文本字段已被保留两次。

此时,如果您想以编程方式切换文本字段,您可以这样做。使用该属性可以使内存管理在这里更加清晰;您只需使用新的自动释放文本字段设置该属性。如果您没有使用过该属性,则必须记住释放它,并可以选择保留新的属性。此时,谁拥有这个新文本字段有些模糊,因为内存管理语义不包含在 setter 中。

现在,假设将另一个视图控制器推送到 UINavigation Controller 的堆栈上,以便该视图不再位于前台。如果出现内存警告,则该离屏视图控制器的视图将被卸载。此时,顶层 UIView 的 view 属性将被清空,它将被释放和释放。

由于 UITextField 被设置为保留的属性,因此 UITextField 不会被释放,因为它的唯一保留是顶级视图的子视图数组的保留。

如果 UITextField 的实例变量没有通过属性设置,它也会存在,因为笔尖加载代码在设置实例变量时保留了它。

这里强调的一个有趣的一点是,由于 UITextField 是通过该属性另外保留的,因此您可能不希望保留它以防出现内存警告。因此,您应该在 -[UIViewController viewDidUnload] 方法中清空该属性。这将摆脱 UITextField 上的最终版本并按预期取消分配它。如果使用该属性,您必须记住显式释放它。虽然这两个操作在功能上是等效的,但意图不同。

如果您选择从视图中删除文本字段而不是换出文本字段,则您可能已经从视图层次结构中删除了它并将属性设置为 nil,或者释放了文本字段。虽然在这种情况下可以编写正确的程序,但在 viewDidUnload 方法中很容易犯过度释放文本字段的错误。过度释放对象是一个导致崩溃的错误;将已经为 nil 的属性再次设置为 nil 是不行的。

我的描述可能过于冗长,但我不想遗漏场景中的任何细节。当您遇到更复杂的情况时,只需遵循这些指南将有助于避免出现问题。

另外值得注意的是,桌面上的 Mac OS X 上的内存管理行为有所不同。在桌面上,设置不带setter的IBOutlet不会保留实例变量;但如果可用的话,再次使用设置器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果我不保留 IBOutlet 会怎样? 的相关文章

  • 步行、自行车和公共交通路线以及每种方式所需的时间,iPhone

    我正在使用以下网址来获取两个位置之间的行车路线 NSString apiUrlStr NSString stringWithFormat http maps google com maps output dragdir saddr dadd
  • CGContextSelectFont 等效项

    在 iOS 7 CGContext SelectFont 中已弃用 已弃用的消息说我必须使用 Core Text 但我不知道哪一个与这段代码完全相同 CGContextSelectFont context Helvetica kBarLab
  • 如何将 UIImageView 裁剪为自定义形状

    用户是否可以在该位周围画一条虚线 圆圈 UIImageView他们希望裁剪到 然后为UIImageView调整大小到这些点 这有点像 Photoshop 中的套索 选取框效果 更新 从 iOS 8 x 开始 UIImageView 提供了m
  • 无需 iPhone 6 Plus 即可预览 iOS 应用程序

    我已经在 Yosemite 中使用 iPhone 6 和 Quicktime 完成了 iOS 应用程序预览 视频 但我无法在 iTunes Connect 中为 iPhone 6 上传它 而且我没有 iPhone 6 设备 有没有办法在没有
  • 与 Objective-C 的 VPN 连接

    有没有办法在 iPhone 的 Objective C 中以编程方式建立 VPN 连接 有这方面的好教程吗 有人知道吗 多谢 我认为第三方应用程序无法访问这些 API
  • 使用特定的 url 启动 UIWebview

    我目前有一个包含四个按钮的视图 并且希望能够启动 UIWebview 并为每个不同的按钮提供特定的 url 我目前可以使用 url 从外部启动 safari 我知道我可以使用代码在每个按钮中显示 UIWebview 并且可以在 UIWebv
  • MKMapView 拦截/劫持 iPhone 触摸事件

    3 0 SDK 是否存在禁用实时缩放并拦截 MKMapView 放大手势的 bug 我有一些真正简单的代码 因此我可以检测点击事件 但有两个问题 放大手势始终被解释为缩小手势 所有缩放手势都不会实时更新地图视图 在 hitTest 中 如果
  • 在情节提要中将 Segue 拖至自身

    我想将一个 Segue 从我的视图控制器拖到其自身 所以我可以推送该特定视图控制器的 无限 实例 我知道如何在代码中执行此操作 即以编程方式实例化视图控制器 但是 我想尽可能使用 segues 我发现了一些在故事板中进行自我延续的 技巧 但
  • 如何为 Nslocal 通知设置自定义重复间隔......?

    我是 iphone 开发新手 我正在尝试在我的项目中使用 NslocalNotification 我需要每 2 小时或每两天或每两个月等给出提醒 目前我正在使用 NslocalNotification 重复间隔 但它仅适用于使用 Ncale
  • 使用 ZBarSDK 时 iPhone 相机失去自动对焦功能

    我正在开发一个应用程序 用户可以选择是否要扫描条形码或拍摄某物的照片 为了拍照 我正在使用UIImagePickerController照常 为了扫描条形码 我使用 ZbarSDK 1 2ZBarReaderViewController 拍
  • 如果我在 iTunes Connect 中点击“拒绝二进制文件”来提交更新的二进制文件,我会失去排队的位置吗?

    我已通过 iTunes Connect 向 App Store 提交了一个应用程序 状态为 审核中 我不知道这是否意味着他们真的开始关注它 我怀疑这只是意味着它已被放入审阅者队列中 在它发布之前我想添加一个调整 但是 如果这意味着点击 拒绝
  • Facebook iPhone SDK:上传图像时显示进度条

    我想在我的 iPhone 应用程序将图像上传到 Facebook 时显示进度条 是否可以 我可以对我发出的每个 FBRequest 执行此操作吗 我还使用 FBRequest 来检查扩展权限 有时需要花费很多时间 谢谢 对于进度条 您可以做
  • 查找已用应用程序名称的捆绑包/开发人员

    我正在尝试将应用程序上传到应用程序商店并收到以下错误 很容易理解 The App Name you have entered has already been used 该应用程序不在 iTunes 上 有什么方法可以找出谁拥有该应用程序或
  • 应用程序打开时处理推送通知

    我正在运行推送通知 有用 我收到通知并使用 application didReceiveRemoteNotification 获取传入数据 然后将用户发送到必要的屏幕 问题是 如果您正在使用该应用程序并收到通知 它会跳转到目标屏幕 而不会发
  • 如何将iPhone/iPad应用程序更改为仅iPhone?

    我有点愚蠢 将我的应用程序构建为同时针对 iPhone 和 iPad 而实际上它应该只针对 iPhone 如何更改设置以使构建仅适用于 iPhone 我实际上已经完成了应用程序的编码并准备提交它 所以希望这只是更改一些晦涩的项目设置的情况
  • AVCaptureSession 具有多个方向问题

    我正在尝试实现条形码扫描仪 我有一个 AVCaptureSession 它从 AVCaptureDevice 接收视频 我想支持所有方向 使用以下代码 当我运行应用程序时 纵向一切正常 然而 在横向方向上 视图会旋转 但视频输入不会旋转 所
  • UIImagePickerView 控制器 - 图像路径 - iphone

    UIImagePickerView控制器返回NSData的图像 我的要求是将图像的路径存储为 varchar 数据类型 从中选择图像后UIImagePickerView 如何获取iPhone照片库中所选图片的完整路径 我的应用程序不必担心在
  • 关于窗口层次结构的警告

    我的调试器中出现这样的警告 这是什么意思 Warning Attempt to present
  • 使用 MFMailComposeViewController 类从 iPhone 应用程序发送带有 IMG 标签的 HTML 电子邮件

    我正在使用 MFMailComposeViewController 类从我的 iPhone 应用程序发送格式化的 HTML 电子邮件 我需要在电子邮件中包含图像 并且我在电子邮件正文中添加了 IMG 标签 IBAction shareWit
  • 填充 CoreData 创建的 sqlite 数据库

    我有一个由 CoreData 模型自动创建的 sqlite DB 但我的应用程序不会让用户能够将数据写入其中 而是我想用程序所需的所有数据预先填充它 我的问题是 CoreData 创建的 sqlite DB 具有未知的表和字段 这些表和字段

随机推荐