Ios 如何使用Bolts框架[Facebook+;Parse]
刚才我从Facebook上看到了关于IOS框架的内容 我可以将此视为主要概念: bolt中的第一个组件是“任务”,它使复杂异步代码的组织更易于管理 但我没有得到这个。我对Ios 如何使用Bolts框架[Facebook+;Parse],ios,facebook,parse-platform,bolts-framework,Ios,Facebook,Parse Platform,Bolts Framework,刚才我从Facebook上看到了关于IOS框架的内容 我可以将此视为主要概念: bolt中的第一个组件是“任务”,它使复杂异步代码的组织更易于管理 但我没有得到这个。我对螺栓框架感到困惑。如何使用它(它是否与web服务或JSON响应解析相关) 他们用parse SDK提供了ParseObject的示例,但我不知道,他们也没有提供任何Xcode项目的示例 Facebook提供了这方面的信息。但我不知道如何与我的项目整合 他们提供的代码非常混乱: [[object saveAsync:obj] co
螺栓框架
感到困惑。如何使用它(它是否与web服务或JSON响应解析相关
)
他们用parse SDK提供了ParseObject
的示例,但我不知道,他们也没有提供任何Xcode项目的示例
Facebook提供了这方面的信息。但我不知道如何与我的项目整合
他们提供的代码非常混乱:
[[object saveAsync:obj] continueWithBlock:^id(BFTask *task) {
if (task.isCancelled) {
// the save was cancelled.
} else if (task.error) {
// the save failed.
} else {
// the object was saved successfully.
SaveResult *saveResult = task.result;
}
return nil;
}];
我们可以下载这个框架。有人能解释一下吗
更新:我收到了一些关于螺栓新问题的答案
示例:
假设您希望从AssertLibrary加载所有图像,并在加载时将所有图像调整为标准大小,因此如果使用主线程执行,则会被击中。在这里,如果你采用异步操作方式,如何使用BFTask呢?另一个例子。有一次,你试图用异步操作调用10个webservice并行,你怎么能把GCD与BFTask一起使用呢?Bolt很棒。同意文档现在有点不集中。下面是一个简单的例子:
// the completion source is the *source* of the task...
BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource];
[self asynchronousMethodWithCompletion:^(id response, NSError *error) {
// your task completed; inform the completion source, which handles
// the *completion* of the task
error ? [source setError:error] : [source setResult:entity];
}];
[source.task continueWithBlock:^id(BFTask *task) {
// this will be executed after the asynchronous task completes...
}];
我发现它对于组完成(半伪代码)特别有用:
这是一种更简洁的方法,可以使用调度组执行其他操作。不过,在串行和并行任务的排序等方面,还有很多
希望这能帮助您入门。下面是一个完整的应用程序示例,它可以支持多个参与者在处理网络请求和用户交互时更改数据 我已经为自己设置了一个指导原则,在接触任何与线程安全相关的服务时,使用链接到串行调度队列的BFExecutor 指出其他最佳实践会很有用,谢谢
#import <Bolts/Bolts.h>
dispatch_queue_t serialQueue;
BFExecutor *serialExecutor;
BFTask *maintask;
int32_t key = 0;
BOOL initialized = FALSE;
@implementation yAppDelegate
- (void)setKey:(int32_t)key_ {
// Don't worry about success, just appending to outstanding tasks
maintask = [maintask continueWithExecutor:serialExecutor withBlock:^id(BFTask *task) {
BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource];
key = key_;
NSLog(@"set key to %d", key);
[source setResult:nil];
if (initialized) {
[self initialize];
}
return source.task;
}];
}
- (BFTask *)downloadConfig {
BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource];
dispatch_async(serialQueue, ^{
NSLog(@"working on init config, key = %d...", key);
// Trigger from a different queue
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[source setResult:nil];
});
});
return source.task;
}
- (BFTask *)initializeService {
BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource];
dispatch_async(serialQueue, ^{
NSLog(@"working on init service, key = %d...", key);
// Trigger from a different queue
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[source setResult:nil];
});
// Set final state
initialized = TRUE;
});
return source.task;
}
- (void)initialize {
int32_t oldKey = key;
__block bool reinit = false;
// Start by chaining it to whatever task is in flight without regard to success
// Everything should use the serialQueue or serialExecutor for thread safety
maintask = [[[maintask continueWithExecutor:serialExecutor withBlock:^id(BFTask *task) {
if (oldKey != key) {
NSLog(@"key out of date (%d != %d). reinitializing...", oldKey, key);
reinit = true;
return [BFTask cancelledTask];
}
return [self downloadConfig];
}] continueWithExecutor:serialExecutor withSuccessBlock:^id(BFTask *task) {
if (oldKey != key) {
NSLog(@"key out of date (%d != %d). reinitializing...", oldKey, key);
reinit = true;
return [BFTask cancelledTask];
}
return [self initializeService];
}] continueWithExecutor:serialExecutor withBlock:^id(BFTask *task) {
if (oldKey != key) {
NSLog(@"key out of date (%d != %d). reinitializing...", oldKey, key);
reinit = true;
}
if (task.error || task.exception || task.isCancelled) {
if (reinit) {
[self initialize];
}
return nil;
} else {
NSLog(@"initService completed = %d", key);
return nil;
}
}];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
serialQueue = dispatch_queue_create("serial", NULL);
serialExecutor = [BFExecutor executorWithDispatchQueue:serialQueue];
// Start with an empty task so all tasks can be strung together without need to initialize
maintask = [BFTask taskWithResult:nil];
// Everything related to changing service state should be contained with the serialQueue dispatch queue
[self setKey:1];
[self initialize];
[self setKey:2];
[self setKey:3];
dispatch_async(dispatch_get_main_queue(), ^(void){
[self setKey:4];
});
dispatch_async(serialQueue, ^(void){
[self setKey:5];
});
[self setKey:6];
// Override point for customization after application launch.
return YES;
}
@end
有关示例,请参阅测试文件(即TaskTests.m)。Github上的示例是特定于解析的
一般来说,查看为软件编写的测试就足以学习如何使用代码。对不起,我自己找不到太多信息,我还没有尝试将其与我自己的项目集成。谢谢@itsthejb查看此链接。你的答案和这个一样。请看这些评论。请解释它与异步操作的关系?Bolt旨在包装/封装任何类型的异步任务。您需要做的只是在操作完成时向任务完成源发送消息。我的想法是用这种方式来包装你的任何行动。是的,我知道。但是上面的任务在哪里可以找到异步任务呢?您是在异步任务完成后而不是在异步任务期间处理BFTask的?我说得对吗?我想知道,如何在异步任务中使用BFTask,特别是在哪里使用BFTask锁定和解锁资源?我会给你+1的方法吗?如果你不明白我的意思,请发表评论。或者在这方面做更多的研究并帮助我。谢谢:)我认为你误解了框架的目的。Bolts不帮助您编写异步操作。其目的是使用公共接口封装和排序操作
#import <Bolts/Bolts.h>
dispatch_queue_t serialQueue;
BFExecutor *serialExecutor;
BFTask *maintask;
int32_t key = 0;
BOOL initialized = FALSE;
@implementation yAppDelegate
- (void)setKey:(int32_t)key_ {
// Don't worry about success, just appending to outstanding tasks
maintask = [maintask continueWithExecutor:serialExecutor withBlock:^id(BFTask *task) {
BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource];
key = key_;
NSLog(@"set key to %d", key);
[source setResult:nil];
if (initialized) {
[self initialize];
}
return source.task;
}];
}
- (BFTask *)downloadConfig {
BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource];
dispatch_async(serialQueue, ^{
NSLog(@"working on init config, key = %d...", key);
// Trigger from a different queue
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[source setResult:nil];
});
});
return source.task;
}
- (BFTask *)initializeService {
BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource];
dispatch_async(serialQueue, ^{
NSLog(@"working on init service, key = %d...", key);
// Trigger from a different queue
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[source setResult:nil];
});
// Set final state
initialized = TRUE;
});
return source.task;
}
- (void)initialize {
int32_t oldKey = key;
__block bool reinit = false;
// Start by chaining it to whatever task is in flight without regard to success
// Everything should use the serialQueue or serialExecutor for thread safety
maintask = [[[maintask continueWithExecutor:serialExecutor withBlock:^id(BFTask *task) {
if (oldKey != key) {
NSLog(@"key out of date (%d != %d). reinitializing...", oldKey, key);
reinit = true;
return [BFTask cancelledTask];
}
return [self downloadConfig];
}] continueWithExecutor:serialExecutor withSuccessBlock:^id(BFTask *task) {
if (oldKey != key) {
NSLog(@"key out of date (%d != %d). reinitializing...", oldKey, key);
reinit = true;
return [BFTask cancelledTask];
}
return [self initializeService];
}] continueWithExecutor:serialExecutor withBlock:^id(BFTask *task) {
if (oldKey != key) {
NSLog(@"key out of date (%d != %d). reinitializing...", oldKey, key);
reinit = true;
}
if (task.error || task.exception || task.isCancelled) {
if (reinit) {
[self initialize];
}
return nil;
} else {
NSLog(@"initService completed = %d", key);
return nil;
}
}];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
serialQueue = dispatch_queue_create("serial", NULL);
serialExecutor = [BFExecutor executorWithDispatchQueue:serialQueue];
// Start with an empty task so all tasks can be strung together without need to initialize
maintask = [BFTask taskWithResult:nil];
// Everything related to changing service state should be contained with the serialQueue dispatch queue
[self setKey:1];
[self initialize];
[self setKey:2];
[self setKey:3];
dispatch_async(dispatch_get_main_queue(), ^(void){
[self setKey:4];
});
dispatch_async(serialQueue, ^(void){
[self setKey:5];
});
[self setKey:6];
// Override point for customization after application launch.
return YES;
}
@end
set key to 1
key out of date (0 != 1). reinitializing...
key out of date (0 != 1). reinitializing...
set key to 2
set key to 3
set key to 6
set key to 5
key out of date (1 != 5). reinitializing...
key out of date (1 != 5). reinitializing...
working on init config, key = 5...
working on init service, key = 5...
initService completed = 5
set key to 4
working on init config, key = 4...
working on init service, key = 4...
initService completed = 4