【问题标题】:Memory management with delegates?与代表的内存管理?
【发布时间】:2010-06-22 15:06:52
【问题描述】:

使用委托进行内存管理,据我了解,我不保留委托,如果视图被卸载(通过 viewDidUnload)然后重新创建(通过 viewDidLoad),我有点不确定如何处理委托?

@property(assign) SomeClass *someDelegate;

.

- (void)viewDidLoad {
    [super viewDidLoad];
    someDelegate = [[SomeClass alloc] init];
    [someDelegate setDelegate:self];
}

-(void)viewDidUnload {
    [super viewDidUnload];
    [self setSomeDelegate:nil];
}

-(void)dealloc {
[super dealloc];
}

PS:我可能走错了路,我只是想弄清楚这个......

干杯加里

【问题讨论】:

  • 已编辑以反映 Deans 更正/cmets。

标签: ios iphone objective-c cocoa-touch delegates


【解决方案1】:

如果您对属性使用 assign,则不会在对象上调用 retain。

这意味着你绝对不应该在它上面调用 release 或 autorelease!

你在你的交易中的行

[someDelegate release];

将来某个时候会导致崩溃 - 您应该删除它。你不需要关心 dealloc 方法中分配的属性。

你的线路

[self setSomeDelegate:nil];

不会泄漏。


但是,您的 viewDidLoad 方法中似乎有 [[someDelegate alloc] init]。这是不寻常的;委托是一个外部对象是正常的,而不是你自己制作的。在您的情况下,它并不是真正的委托,它只是一个为您做某事的对象 - 您应该重命名它并将属性更改为保留(并记住在 dealloc 中释放它)。

目前,如果您的属性设置为 (assign) 并且其他人设置了它,您将泄露您的初始委托。如果你只在这个类中使用委托,也许它根本不应该是一个属性?如果您只想能够从课堂外阅读它,您可以使用(只读)而不是分配(并将[self setSomeDelegate:nil] 更改为someDelegate=nil;

您在viewDidUnload 中将代表设置为 nil 的行消除了您在第二条评论中提出的问题 - 您正在删除代表,所以当您再次到达 viewDidLoad 时,您的代表已经是 nil :)

【讨论】:

  • 是的,我明白了,谢谢迪恩。我对@property(assign) 的工作方式感到困惑。
  • 鉴于我在 viewDidLoad 中有一个 [[someDelegate alloc] init] 如果视图卸载并再次调用 viewDidLoad 会发生什么?每次我调用 viewDidLoad 我都会得到一个新的 someDelegate 并泄露旧的?
  • 感谢 Dean,我想我可以看到发生了什么,我想我的想法有误,现在我正在努力让它发挥作用。我会将您的答案标记为已接受,然后离开并重新考虑。非常感谢...
  • 没问题,还有什么问题可以问:)
【解决方案2】:

This 可能有助于理解原因

您避免保留代表的原因是您需要 避免保留循环:

A 创建 B A 将自己设置为 B 的委托…… A 由其所有者释放

如果 B 保留了 A,A 不会被释放,因为 B 拥有 A,因此 A 的 dealloc 永远不会被调用,导致 A 和 B 都泄漏。

您不应该担心 A 会离开,因为它拥有 B 并因此获得 在 dealloc 中摆脱它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    相关资源
    最近更新 更多