保留“自我”的不良做法?

时间:2010-10-17 13:36:06

标签: iphone cocoa cocoa-touch cocoa-design-patterns

我有一个简单的查询,我想要被某人清理......保留自己是不是很糟糕?

我有一个服务器请求对象,我想做。我希望能够以下列方式使用它:

ARequest *request = [ARequest request: someParam];
request.delegate = self;
[request begin];

为了让对象在自动释放池耗尽后不会自我毁坏,我想我需要在它的init方法中调用retain,然后在收到,处理并传递给它之后调用服务器响应委派。

然而,有些事情正在用这种方法引起我的警钟。更好的方法吗?

4 个答案:

答案 0 :(得分:6)

保留self没有任何问题,只要您根据正常的内存管理协议在某个明确定义的位置释放它。如果一个对象要求自己存在直到某个条件满足,那么它应该对此负责,就像它对继续存在所需的任何其他对象一样。

引入其他无关的管理者对象或者出于迷信的原因而将责任归咎于对象的所有者将是真正的反模式。

(垃圾收集代码中的等效方法是让对象在结果挂起时将自己从垃圾收集中排除,或者如果您不喜欢这个想法,则通过某种集合将其置为根。)

答案 1 :(得分:2)

这并非闻所未闻,但有点不常见。我看到它使用的主要方式(并自己使用它)是当你处理某种半同步对象时(通过半同步我的意思是它不会阻塞主线程,但它也不会在后台线程上执行; NSURLConnection适合此帐单)。例如,我编写了一个NSWindowController的子类,专门用于将窗口显示为工作表并调用某些特定的委托回调。基本上,您需要alloc / init一个新的工作表控制器并调用beginSheetForWindow:。这将半张同步运行工作表,然后在工作表被解除时调用适当的回调。

由于调用对象不一定“拥有”工作表(将其视为iOS上的模式视图控制器的Mac版本),工作表控制器会在显示工作表之前立即执行[self retain],并且{清理并调用回调后立即{1}}。这背后的目的是确保控制器对象在工作表完成之前保持不变。 (表格,IIRC,由runloop保留,但我还需要控制器留下来)

就像我说的那样,很少遇到你想要[self release]的情况,但这并非不可能。但是,作为一般经验法则,如果您认为需要[self retain],则可能需要重新考虑。

答案 2 :(得分:1)

最简单的方法是为您的请求创建一个iVar,在启动时保留请求,并在调用最后一个委托方法时释放它。

ARequest是您创建的课程吗?它是否创建了一个新的线程来异步提交请求?

答案 3 :(得分:0)

我曾经和你做过同样的事情。我在NSString上编写了一个Category-Method,将它发送到服务器,然后打印出来。在类别方法中,我不得不调用[self retain],以便回调方法可以是NSString-Categroy-Method to。
我觉得很糟糕,我重新编写了所有内容以使用Singleton,可以通过Category-Method访问。因此,Singleton将在必要时保留字符串。