我使用调用类作为委托创建了一个NSURLConnection。 我在我的测试设备上构建了这个,然后才意识到我从未将对象声明为观察协议,但它已经运行了(我会说通常,但我认为我完全搞砸了我的应用程序围绕多个线程)。
那么没有必要将对象声明为实现委托吗?
我也没有包含所有必需的委托方法,它仍然调用委托方法。
这个项目还有其他人,而且它相当大,所以委托协议可能被宣布在某个地方模糊不清,但是在标题和实现声明中搜索它时我没有看到它。
答案 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对initWithRequest
和connectionWithRequest
的实际定义,它们的定义如下:
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;
+ (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;
正如您将看到的,delegate
参数定义为id
,未指定任何明确的正式协议,因此,如果传递给它的对象,您将不会收到警告不会被定义为符合任何特定协议。
因此,在回答您的问题时,在这种特殊情况下,您不必必须定义委托以符合任何特定协议。在许多其他情况下,delegate
属性被定义为采用符合适当协议的指针,因此编译器会在您的对象不符合时发出警告。但不是在这种情况下。
毋庸置疑,您可能应该继续并确定您所遵循的协议,因为它可以使您的代码更清晰,并且当您开始编写时,您至少可以享受Xcode中更好的自动完成功能这些方法之一。但你的问题不是你应该(你应该),而是你必须(你没有)。
作为澄清,在iOS中,现在有两个NSURLConnection
协议,NSURLConnectionDataDelegate
和NSURLConnectionDelegate
。 (这可能就是为什么他们没有在方法声明中定义协议,以避免混淆他们将一些方法转移到这个NSURLConnectionDataDelegate
协议中。)