4

我见过一些 iOS 开发人员使用这样的代码:

- (void)setupWebView:(UIWebView**)aWebView {
 UIWebView *webview = [[UIWebView alloc] init];
.....

 if (*aWebView) {
        [*aWebView release];
    }

    *aWebView = webview;
}

你知道这是什么意思以及我们为什么使用它吗?谢谢

4

3 回答 3

41
- (void)setupWebView:(UIWebView**)aWebView {

那太可怕了。您永远不应该有一个返回 void 的方法,而是通过引用设置参数,除非:

• 有多个参数集

• 方法的前缀是get

该方法应该直接返回创建的实例。这只会让事情变得更糟——完全是错误的:

 if (*aWebView) {
    [*aWebView release];
 }

 *aWebView = webview;
  1. 它破坏了封装;如果调用者传递了对 iVar 插槽的引用怎么办。现在你让被调用者管理调用者的内存,这既是可怕的做法,也很可能会崩溃(例如,面对并发)。

  2. 如果aWebView为 NULL,它会崩溃;特别是在作业上崩溃。

  3. 如果aWebView指的是 iVar 插槽,它会绕过任何可能的属性使用(打破封装的不同方式)。

于 2012-06-13T17:46:52.110 回答
2

它是一种初始化指针的方法。第一行分配对象。if 语句确保传入的指向指针的指针尚未分配,如果是则释放它。然后它将引用的指针设置为新分配的对象。

于 2012-06-13T17:29:06.480 回答
1

@bbum 的答案可能是正确的,但遗漏了我在那里看到的问题的一个方面。Foundation 中有很多在方法签名中使用指针指针的例子,可以说这是一种常见的模式。这些可能不是初学者的错误。

这些示例中的大多数都是相似的,因为它们属于一类:API 尝试避免使用异常,而是使用NSError用于失败。但是因为返回值用于BOOL表示成功的信号,所以NSError指针指针用作输出参数。只有在可能很少见的错误情况下NSError才会创建一个对象,该对象可以包含错误代码和错误描述,以及本地化描述,甚至可能包含更多信息(如批量操作中的多个错误数组)。因此,主要的成功案例是高效的,而错误案例有一定的能力传达出了什么问题,而不诉诸异常。据我了解,这就是这些签名背后的理由。

NSFileManager您可以在和中找到这种用法的示例NSManagedObjectContext

在您想要多个返回值并且数组没有意义的其他情况下(例如,因为这些值的类型不同),人们可能会尝试使用指针指针,但正如@bbum 所说,看起来可能会更好为替代品。

于 2012-06-13T19:35:33.317 回答