Objective-C 委托内存存储空问题

Posted

技术标签:

【中文标题】Objective-C 委托内存存储空问题【英文标题】:Objective-C Delegate Memory Storage null Issue 【发布时间】:2014-05-27 22:33:55 【问题描述】:

我在 Objective-C 中两个 UIViewControllers 之间的委托遇到了麻烦。

我在其中一个UIViewControllers 中创建了代表,它与前一个UIViewController 对话。我在ConfirmDetailsViewController 中声明了代表。 (这是在viewDidLoad 中声明的,以及其他委托代码):

ForthViewController *delegate = [[ForthViewController alloc] init];

我还在.m 文件的@interface 上方添加了正确的#import "ForthViewController.h"

后面几行我将一组本地属性NSStrings 设置为delegate.nameString 的值,这是ForthViewController 中的另一组属性NSStrings,如下所示:

self.nameString = delegate.nameString;
self.emailAddressString = delegate.emailAddressString;
self.phoneNumberString = delegate.phoneNumberString;
self.emergencyPhoneNumberString = delegate.emergencyPhoneNumberString;
self.additionalDonationString = delegate.additionalDonationString;

然后我继续使用NSLogself.nameStringself.emailAddressString 等的值打印到控制台:

NSLog(@"Name: %@", self.nameString);
NSLog(@"Email Address: %@", self.emailAddressString);
NSLog(@"Phone Number: %@", self.phoneNumberString);
NSLog(@"Emergency Phone Number: %@", self.emergencyPhoneNumberString);
NSLog(@"Donation: $%@", self.additionalDonationString);

ForthViewController中将本地属性对象的值赋值给self.nameString等之后,我将它们的值打印到控制台并得到合适的值。然后,当我将对象转移到 ConfirmDetailsViewController 时,我遇到了所有字符串的 (null) 值。

我认为最有可能的错误在于代理在ConfirmDetailsViewController 中的声明方式,但是我在网上看到多个消息来源说这是您设置代理的方式。如何在不丢失它们的值并重置为 null 的情况下正确地通过委托获取正确的值?

如果您对我的解释有疑问,这里有一个示例项目的下载链接,该问题很明显:https://www.dropbox.com/sh/66x89dciu4waxyd/AADdA3ehUglWIDWZGzG08zqpa

编辑

对于那些想知道的人,这就是我在ForthViewController.h 文件和ConfirmDetailsViewController.h 文件中声明NSString 属性的方式:

@property (strong, nonatomic) NSString *nameString;
@property (strong, nonatomic) NSString *emailAddressString;
@property (strong, nonatomic) NSString *additionalDonationString;
@property (strong, nonatomic) NSString *phoneNumberString;
@property (strong, nonatomic) NSString *emergencyPhoneNumberString;

【问题讨论】:

所以ForthViewController 出现在屏幕上,然后出现ConfirmDetails,对吗?如果是这样,你如何呈现ConfirmDetails @user3386109 先显示ForthViewController,然后再显示ConfirmDetailsViewController 您正在创建一个 ForthViewController 实例作为 viewDidLoad 中的局部变量,这意味着一旦 viewDidLoad 退出,视图控制器就会被释放。你实际上需要你的委托是一个属性,它的值是在 ForthViewController 调用 ConfirmDetailsViewController 时分配的。这也不是委托模式,因为委托有一个对象调用另一个对象的方法,通常是为了响应事件 - 例如考虑 UITableViewDelegate。 【参考方案1】:

据我所知,您没有从 ForthViewController 中获得好的值,因为您使用 alloc/init 创建了它。您作为“代表”拥有的对象与您想要的属性具有适当值的对象不同。例如,在您提供的示例项目中,永远不会为您设置为委托的对象调用 saveButton: 方法。

那么,你应该如何设置它?使用@protocol 语法创建一个真正的委托。在第二个视图控制器的标头中定义协议,并使第一个视图控制器订阅该协议。然后添加第二个视图控制器的delegate 属性,该属性要求其值符合协议。当您创建第二个视图控制器的实例时,将其委托属性设置为 self 以建立连接。现在,在您的第二个视图控制器代码中,您可以安全地调用您在委托对象的协议中列出的任何方法。

这是一种委托模式,因为第二个视图控制器可以将消息发送到它不知道的对象。它只知道它的委托可以接收它的消息。

Here is the scoop on protocols, straight from the horse's mouth.

【讨论】:

虽然有道理,但为什么在委派给 AppDelegateAppDelegate *delegate = [[UIApplication sharedApplication] delegate]; 会起作用? 因为sharedApplication是一个返回单例galloway.me.uk/tutorials/singleton-classes的类方法 应用程序的sharedApplication“实例”让代理人像秘书一样。应用程序告诉委托人它在做什么,委托人负责任何补充工作。而且,应用程序不需要知道委托本身的任何信息来完成它的工作除了它可以接收应用程序的消息。

以上是关于Objective-C 委托内存存储空问题的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C09-空指针和野指针

Objective-C / Cocoa:上传图像、工作内存和存储

报亭内存存储问题,如何获取应用缓存目录?

程序集中的空标签占用内存而没有存储指令?

Swift 内存管理:在 var 中存储 func

存储类链接内存管理