是否有必要将对象声明为委托才能使用它?

时间:2013-05-23 22:21:52

标签: ios objective-c delegates nsurlconnection

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

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

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

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

3 个答案:

答案 0 :(得分:4)

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

如果传递的对象未声明它符合NSURLConnectionDelegate,则应该收到编译器警告,指示您传递的是错误类型的对象。仔细检查是否有任何警告。如果没有,那么你的类正确声明它符合协议。

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

你说:“我也没有包含所有必需的委托方法,它仍然调用了委托方法。”这没有意义。如果你不实现它们怎么能被调用?另外,协议中没有必要的方法。

答案 1 :(得分:1)

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

编辑:rmaddy补充说,协议中的所有方法都是可选的。就是这种情况,然后NSURLConnection最有可能用(实例)-respondsToSelector:而不是(类)+conformsToProtocol:进行检查。在这种情况下,实施该方法应该足够了(但你仍然应该在-setDelegate:上发出警告)

答案 2 :(得分:1)

尽管文档说的是,如果你看一下Cocoa对initWithRequestconnectionWithRequest的实际定义,它们的定义如下:

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

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

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

毋庸置疑,您可能应该继续并确定您所遵循的协议,因为它可以使您的代码更清晰,并且当您开始编写时,您至少可以享受Xcode中更好的自动完成功能这些方法之一。但你的问题不是你应该(你应该),而是你必须(你没有)。

作为澄清,在iOS中,现在有两个NSURLConnection协议,NSURLConnectionDataDelegateNSURLConnectionDelegate。 (这可能就是为什么他们没有在方法声明中定义协议,以避免混淆他们将一些方法转移到这个NSURLConnectionDataDelegate协议中。)