回电风格

时间:2009-05-04 17:59:39

标签: iphone objective-c coding-style

我正在编写一个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

3 个答案:

答案 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一样。