我正在编写一个iPhone应用程序,在许多地方需要执行非常简单的请求响应类型的非HTTP或FTP网络。
我把所有这些都包含在一个与run循环集成的SimpleQuery类中。
SimpleQuery *lookup = [[SimpleQuery alloc] init];
[lookup setDelegate:self];
[lookup doQueryToHost:queryServer port:queryPort query:queryString ];
如您所见,调用对象将自身设置为委托。结果完成后,它会在委托上调用一个带有结果的方法。
[delegate simpleQueryResult:resultString simpleQuery:self];
我现在处于一个我有SimpleQuery用户的位置,它有两种类型的查询,所以我需要扩展SimpleQuery来支持它。
我可以想到两种合理的方法。
首先将选择器传递给doQueryString或单独的doQueryStringWithSelector。
[lookup doQueryToHost:queryServer port:queryPort query:queryString selector:@SEL ];
其次将标记传递给doQueryString,以便在调用委托时,它可以在传递simpleQuery时查询标记,以找出结果的用途。
[lookup doQueryToHost:queryServer port:queryPort query:queryString withTag:tag ];
我只是想知道从编码风格的角度来看哪个是最好的,第一个似乎更简单,但标记似乎更符合iPhone SDK和Interface Builder
答案 0 :(得分:2)
Apple代码中常用的选项(例如,在UIControl中)是提供目标对象和选择器。这仅在存在单个回调时才有效,并且在这种情况下比委托更合适。 (如果有多个回调,那么您可能需要使用委托和标记方法。)
如果你走这条路线,那么你完全取消了委托,而是有一个像这样的签名的方法:
doQueryToHost:(id)queryServer port:(int)queryPort query:(NSString*)queryString target:(id)target action:(SEL)action
请注意,在这种情况下,“action”通常优先于方法参数中的“selector”。完成后,查询将简单地调用目标上的选择器。这将允许您的客户拥有多个选择器,以及多个目标对象;这可以帮助清理代码,因为您不需要将所有内容都移动到单个委托对象中。
如果您想使用标记路径,则应将其称为“上下文”,这是Apple使用的(例如,在addObserver:forKeyPath:options:context)。
答案 1 :(得分:1)
第三个选项是套件中的常见模式,即使用@protocol
s。
例如:
@protocol QueryCompleteHandlerProtocol
- (void)queryType1Complete:(int)intStuff;
- (void)queryType2Complete:(float)floatStuff;
@end
这样做是为了声明一组接受采用协议的对象必须符合的方法调用(编译器实际上会强制执行此操作)。
因此,您的SimpleQuery对象将保留类似委托指针的东西,您可以在ivars中声明这样:
NSObject<QueryCompleteHandlerProtocol> *callback;
这告诉编译器callback
是一个从NSObject
下降并采用QueryCompleteHandlerProtocol
协议的对象。有时您会将其视为:
id<QueryCompleteHandlerProtocol> callback;
当你想调用回调时,没有什么特别之处,SimpleQuery
的方法只会调用:
[callback queryType1Complete:1];
[callback queryType2Complete:2.0];
最后,你的procotol类的客户端将声明自己采用协议:
@interface MyClass : NSObject<QueryCompleteHandlerProtocol>
...
@end
并将自己设置为回调,其代码如下:
[lookup setCallback:self];
这是编译器检查MyClass
是否符合QueryCompleteHandlerProtocol
的地方,这意味着它已实现queryType1Complete:
和queryType2Complete:
。
答案 2 :(得分:1)
我不确定我在这里理解这个问题。 SimpleQuery的用户不能为第二个查询设置另一个委托对象,或者在simpleQuery:参数上设置分支吗?这是委托模式的基本部分,就像为一个视图控制器提供两个UIActionSheets一样。