【问题标题】:Releasing a parameter释放参数
【发布时间】:2011-04-07 18:42:05
【问题描述】:

假设您有班级在其他线程上做某事。并且有自己的代表。

@protocol XRequestDelegate;

@interface XRequest : NSObject {
    id<XRequestDelegate> delegate;
}
@property (nonatomic, retain) id<XRequestDelegate> delegate;

- (void) doSomething;
@end


@protocol XRequestDelegate <NSObject>

- (void)request:(XRequest *)request didFinish:(id)object;
- (void)request:(XRequest *)request didFailWithError:(NSError*)error;

@end

doSomething 最终会调用 request:didFinish:request:didFailWithError:

让我们在我们的对象中使用这个类;

- (void)doRequest
{
    XRequest *request = [[XRequest alloc] init];
    [request setDelegate:self];
    [request doSomething];
}

- (void)request:(XRequest *)request didFinish:(id)object
{
    // Use object whatever you want
    [request release];
}

- (void)request:(XRequest *)request didFailWithError:(NSError *)error
{
    //Log Error
    [request release];
}

我们有一个XRequest 的实例分配并最终在方法中释放。

我们可以说这是一种错误的内存管理方式吗?我们是否应该扩大XRequest对象的范围?

【问题讨论】:

  • 在这种情况下,我会将 doSomething 设为类方法 (+)。否则,您需要实例化一个除了实例化另一个对象之外什么都不做的对象。

标签: objective-c memory-management protocols


【解决方案1】:

Apple 的 fundamental rule of memory management 声明:

您只释放或自动释放您拥有的对象。

我认为在这种情况下,您不会违反该规则,因为您的委托是分配请求的对象。但是,您确实提到了多个线程,最佳实践是每个线程有一个对象(不要在一个线程上分配请求并在另一个线程上释放它)。

【讨论】:

  • 如您所见,分配和释放对象在同一个线程上。我的意思是在doSomething 方法中会有更多线程化进程。
  • 我也在同一个内存地址释放我自己的对象。分配的对象和引用的对象是相同的。不会有替代的情况。此外,我没有任何机会释放我的对象超过我分配(或保留)
  • @Alkimake 我看不到您的委托方法在同一个线程上被调用,因为您没有显示doSomething 的代码,但如果是这种情况,那么我认为你很好。
【解决方案2】:

我见过苹果的例子是这样做的(我相信它是媒体播放器的例子之一),但我会说这是一种错误的内存管理方式。如果引用XRequest 的类在XRequest 完成之前被释放,会发生什么?你如何防止任何进一步的委托调用或释放它。

您要做的是将请求保留在 ivar 中,然后删除其委托并释放它,并在完成/失败方法和 -(void)dealloc 中将其设置为 nil。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    • 2011-11-09
    • 2017-10-16
    • 2012-10-06
    • 2013-03-24
    相关资源
    最近更新 更多