2012-06-13 48 views
4

我已经看到了使用这样的代码在某些iOS developpers:如何使用指针的目标C

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

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

    *aWebView = webview; 
} 

你知道what'is这意味着,以及为什么我们用这个?谢谢

+0

这与C或C++有什么关系?它是Objective-C! – chris

+0

,因为我从来没有看到它在目标c! – samir

+0

@SamirGuerdah:重要的是要记住Objective-C是C的一个严格超集。任何在C中有效的东西在Objective-C中都是有效的。在与一个严格的C模块接口时,我写了很多这样的代码。 – Kyle

回答

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

这太可怕了。你应该永远必须返回void的方法,而是通过引用,除非设置参数:•方法与get

这种方法应该简单地返回前缀

•有多个参数设置

直接创建的实例。而这只是使情况变得更糟 - 是平了错误:

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

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

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

  3. 如果aWebView引用了一个iVar插槽,它绕过了任何可能的属性使用(破坏封装的不同方式)。

2

这是一种初始化指针的方法。第一行分配对象。 if语句确保传入的指针指针不被分配,如果它释放它。那么它将引用的指针设置为新分配的对象。

+0

这是目标c中的一个好习惯吗? – samir

+0

“良好做法”是主观的。如果你正在寻找一个理由来指定一个编码器,你不喜欢我会说找到别的东西,这是一个合理的事情。 –

+12

这是可怕的做法。 – bbum

1

通过@bbum答案很可能是正确的,但一方面省去了给我看有问题。 Foundation中有很多例子在方法签名中使用指针指针,所以你可以说它是一种常见的模式。而这些可能不是初学者的错误。

这些例子中的大部分类似,因为它们属于一类:API试图避免例外的使用,而使用NSError来表示失败。但是由于返回值用于表示成功的BOOL,因此将指针指针用作输出参数。只有在可能罕见的错误情况下,才会创建一个NSError对象,其中可能包含错误代码和错误描述,以及本地化描述,甚至可能包含更多信息(如批量操作中的多个错误数组)。所以主要的成功案例是高效的,错误案例有一定的权力来沟通出错的地方,而不诉诸例外。这是我理解这些签名背后的理由。

您可以在NSFileManagerNSManagedObjectContext中找到此用法的示例。

在其他情况下,如果您想要多个返回值并且数组没有意义(例如因为值不是相同类型),可能会试图使用指针指针,但正如@bbum所说,它很可能更好地去寻找替代品。

+4

“... API试图避免异常的使用......”更确切地说,API使用程序员错误的异常,以及输入错误和其他运行时问题的错误。例如,'[myArray objectAtIndex:[myArray count]]'会导致一个异常(你说的没有意义),但是'BOOL successfullyDeleted = [myFileMgr removeItemAtURL:myURLToAFileThatDoesntExist error:&error]'将返回NO并且一个错误(你说的话有道理,但不能完成)。 –

+2

这不会使指针指针变得很常见,它使得指针指针可以有选择地提供常见的错误细节。巨大差距。而且,正如彼得所说的那样,这不是“避免”异常,而是异常是*不可恢复的,而使用NSError则是可以恢复的。 – bbum

+0

@bbum这很好地避免了异常。我没有说出于什么原因,但这并没有说错。你想争辩还是想回答问题?顺便说一句。我并没有说你的答案可能是正确的,会让你烦恼,但要表明我不想就此做出最后的呼叫。什么样的用法使得指针指针“常见”可能是一些无法回答的问题,除非有更多的“通用”限定条件。 – febeling