【问题标题】:Is it necessary to declare an object as a delegate to use it as such?是否有必要将对象声明为委托才能使用它?
【发布时间】:2013-05-23 22:21:51
【问题描述】:

我用调用类作为委托创建了一个 NSURLConnection。 我在我的测试设备上构建了它,然后才意识到我从未将对象声明为遵守协议,但它运行了(我会说正常,但我认为我完全把我的应用程序搞砸了多个线程)。

那么就没有必要将对象声明为实现委托了吗?

我也没有包含所有必需的委托方法,它仍然称为委托方法。

这个项目还有其他人,而且它相当大,所以也许委托协议被声明在某个模糊的地方,但我在标题和实现声明中搜索它时没有看到它。

【问题讨论】:

  • 愤怒的暴徒请注意:如果可能的话,我不打算破坏协议的协议,我只是对强制执行而不是强制执行的边界感到好奇。
  • 所有需要的是该类支持委托协议定义的方法。该类本身不需要采用协议。 (理论上,委托的“消费者”可以明确检查委托是否采用协议,但许多“消费者”不太可能这样做。)
  • 对于任何好奇的路人来说,我的困惑之源。 developer.apple.com/library/mac/#documentation/Foundation/…

标签: ios objective-c delegates nsurlconnection


【解决方案1】:

NSURLConnection initWithRequest:delegate: 方法的delegate 参数定义为id<NSURLConnectionDelegate> 类型。

如果你传递的对象没有声明它符合NSURLConnectionDelegate,你应该得到一个编译器警告,指出你传递了错误类型的对象。仔细检查您是否收到任何警告。如果不是,那么您的类在某个地方正确声明它符合协议。

在运行时,唯一的要求是委托对象实际上至少实现了委托所需的方法。但在这种情况下,协议中没有必需的方法。它们都是可选的。

您说:“我也没有包含所有必需的委托方法,它仍然称为委托方法。”这没有意义。如果您不实施它们,如何调用它们?另外,协议中没有必需的方法。

【讨论】:

  • 发现警告,声明 。我一直在查看 OSX 应用程序的文档,所以我的一些信息是有偏差的。我没有意识到所有方法对于 iOS 都是可选的。我并不是要暗示我调用了不存在的委托方法,我的意思是我认为我只实现了一些必需的方法,而不是其他方法。不过,感谢您的澄清。
  • +1 顺便说一句,文档说它被定义为id<NSURLConnectionDelegate>,但如果你查看标题,它实际上被简单地定义为id,可能是因为大部分委托方法我们在 iOS 中编写的连接是 NSURLConnectionDataDelegate 方法,而不是 NSURLConnectionDelegate 方法。
【解决方案2】:

我认为这取决于NSURLConnection 的实现方式。首先,如果setDelegate: 方法/属性设置为接受id<NSURLConnectionDelegate> 类型的对象,那么编译器应该警告您。如果NSURLConnection 源代码在调用任何协议方法之前使用(例如)+conformsToProtocol: 检查委托,则不应回调您的对象。

编辑:rmaddy 补充说协议中的所有方法都是可选的。既然如此,那么NSURLConnection 最有可能使用 (instance)-respondsToSelector: 而不是 (class)+conformsToProtocol: 进行检查。在这种情况下,实现该方法就足够了(但您仍然应该在-setDelegate: 上收到警告)

【讨论】:

    【解决方案3】:

    不管文档怎么说,如果您查看 Cocoa 对 initWithRequestconnectionWithRequest 的实际定义,它们的定义如下:

    - (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;
    + (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;
    

    如您所见,delegate 参数被定义为 id,没有指定任何明确的正式协议,因此,如果您传递给它的对象没有发生,您将不会收到警告被定义为符合任何特定协议。

    因此,在回答您的问题时,在这种特殊情况下,您不必必须定义委托以符合任何特定协议。在许多其他情况下,delegate 属性被定义为采用符合适当协议的指针,因此如果您的对象不符合,编译器会警告您。但在这种情况下不是。

    不用说,您可能应该继续定义您要遵循的协议,因为它使您的代码更加清晰,并且您至少会在开始编写时享受 Xcode 中更好的自动完成功能这些方法之一。但你的问题不是你是否应该(你应该),而是你是否必须(你不应该)。

    澄清一下,在 iOS 中,现在有两个 NSURLConnection 协议,NSURLConnectionDataDelegateNSURLConnectionDelegate。 (这可能是他们没有在方法声明中定义协议的原因,以避免与将某些方法转换为 NSURLConnectionDataDelegate 协议时混淆。)

    【讨论】:

      猜你喜欢
      • 2011-09-07
      • 1970-01-01
      • 1970-01-01
      • 2016-12-05
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-01
      相关资源
      最近更新 更多