我正在尝试通过其他公司以及 Apple 的示例进行跟进。我迷路了。
我有一个单例类,用于处理我的用户登录(挑战 Web 服务器等)。
我想创建一个我可以调用的 block ,传入用户名/密码。该 block 将执行 Web 服务调用,然后返回是否成功。
到目前为止,这是我设法开始工作的:
我的单例类是这样的:
.h
typedef void (^AMLoginBlock)(NSString *userName, NSString *password);
@interface AuthManager : NSObject
+ (id)sharedManager;
+ (bool)loginUserWithBlock:(AMLoginBlock)block;
@end
.m
@implementation AuthManager
+ (id)sharedManager
{
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init]; // or some other init method
});
return _sharedObject;
}
+ (bool)loginUserWithBlock:(AMLoginBlock)block {
NSLog(@"im printing from AM");
return true;
}
@end
然后我像这样调用方法:
bool rtn = [AuthManager loginUserWithBlock:^(NSString *userName, NSString *password) {
NSLog(@"im here in the block LVC.");
}];
我的问题分为三部分:
如何为类似于
UIView animation...
block 的 block 编写完成处理程序。从基于 block 的实现中执行这些 Web 服务调用是个好主意吗?
我应该像这样声明 block 方法吗:
- (bool)loginUserWithBlock:(AMLoginBlock)block;
而不是使用 +(bool)loginUser..
因为它在单例类中。不确定这是否会导致创建单例的多个实例。
我的目标是能够像调用 [UIView animation..]
一样调用此 block 。所以我可以简单地做:
[AuthManager loginUserWithUsername:foo
password:bar1
completion:^(BOOL finished) {
if (finished)
//push new view controller.
else
//spit out error
}];
最佳答案
完成处理程序
您需要将完成 block 复制到 iVar 类:
@property (nonatomic, copy) void (^completionHandler)(bool *);
因为您正在保存 block ,所以您需要让一个非类方法获取该 block (请参阅下文了解如何在不违反单例的情况下执行此操作)。您的方法示例可以是:
- (void)loginUserWithUsername:(NSString *)username
password:(NSString *)password
completion:(void(^)(bool *finished))completionBlock
{
// Copy the blocks to use later
self.completionHandler = completionBlock;
// Run code
[self doOtherThings];
}
然后当您的登录代码完成其工作时,您可以调用该 block - 这里我将 self.error,一个 bool
传递给该 block :
- (void)finishThingsUp
{
// We are done with all that hard work. Lets call the block!
self.completionHandler(self.error);
// Clean up the blocks
self.completionHandler = nil;
}
好主意
好吧,这是一个哲学问题,但我会这样说:Objective-C 中的 block 允许您编写执行单个任务的代码,并轻松地将其集成到多个程序中。如果您选择不在登录代码中使用完成处理程序,则需要您的登录代码:
- 要求使用它的类实现一个协议(protocol)(如在
LoginDelegate
中) - 使用其他一些系统来通知您的代码,例如 Key Value observing 或 Notifications
- 将其硬编码为仅适用于一种类型的调用类
以上任何一种方法都可以,我觉得基于 block 的回调系统是最简单和最灵活的。它允许您只使用您的类而不用担心额外的基础设施(设置通知、遵守协议(protocol)等),同时仍然允许您在其他类或程序中重用它。
辛格尔顿
在 Objective-C 中以 +
开头的方法是类方法。您不能使用类方法来操作 iVar,因为谁会拥有该数据?
您可以做的是拥有一个始终返回该类的相同实例的类方法,从而允许您拥有一个可以拥有数据的对象,但避免拥有多个对象。
This excellent Stack Overflow answer has sample code .
祝你好运!
关于objective-c - 编写我自己的 block 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12399534/