iOS - 如何使用循环增加块中的变量
iOS - How to increase variable in block using cycle
我需要在服务器上创建一个实体,然后将几张图片上传到服务器。
所以首先阻止显示成功在服务器上创建实体然后我开始循环上传 10 张图片,但是应用程序不会在最后 10 张图片上传后发送通知,所以 'i' 变量可以是10 甚至不是订单中的 10。我不确定,但似乎块中的迭代不正确。所以我只想确保这 10 张图片已上传,然后调用发送通知。
所以我跳过了一些块参数和失败选项,我用于获取要上传的图像的数组等。只需将我的块作为在“{”之后显示成功调用的示例。
// success first block
block1
{
// cycle from 0 to 10
for (NSInteger i = 0; i <=10; i++)
{
// success upload image to the server block
block2
{
// if I did 10 uploads I need to send notification.
if (i == 10)
{
// send notification here when last block returned success....
}
}
}
}
您可以使用如下派发组。
// success first block
block1
{
dispatch_group_t group = dispatch_group_create();
// cycle from 0 to 10
__block NSUInteger successCount = 0;
for (NSInteger i = 0; i <=10; i++)
{
dispatch_group_enter(group);
// upload image to the server block
successOrErrorBlock
{
if (success)
successCount++;
dispatch_group_leave(group);
}
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
if (successCount == 10) {
// send notification here when last block returned success....
}
});
}
我在异步调用多个块时遵循的模式是创建待办事项列表(数组)并递归执行该列表,如下所示:
// say this is our asynch operation. presume that someParameter fully
// describes the operation, like a file to be uploaded
- (void)performSomeAsynchOperationDefinedBy:(id)someParameter completion:(void (^)(BOOL, NSError *))completion {
// this could wrap any operation, like anything from AFNetworking
}
- (void)doOperationsWithParameters:(NSArray *)parameters completion:(void (^)(BOOL, NSError *))completion {
if (!parameters.count) return completion(YES, nil);
id nextParameter = someParameters[0];
NSArray *remainingParameters = [parameters subarrayWithRange:NSMakeRange(1, parameters.count-1)];
[self performSomeAsynchOperationDefinedBy:nextParameter completion:^(BOOL success, NSError *error)) {
if (!error) {
[self doManyOperations:remainingParameters completion:completion];
} else {
completion(NO, error);
}
}];
}
现在,要执行多个操作,请将参数放在一个数组中,例如:
NSArray *parameters = @[@"filename0", @"filename1", ...];
[self doOperationsWithParameters:parameters completion:(BOOL success, NSError *error) {
NSLog(@"ta-da!");
}];
上面的变体在每次递归之前和之后调用进度块(具有进度百分比 initialCount/remainingCount
)应该直接从提供的示例开始。
另一种变体是将参数数组和完成块都包装在一个 NSObject 中,因此可以使用 performSelector:
进行递归调用,这样做的好处是不会结束堆栈在长递归上。
如果您正在创建一堆 AFHTTPRequestOperation
对象,那么最合乎逻辑的方法是创建一个完成操作并使其依赖于请求操作:
NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
// code to be run when the operations are all done should go here
}];
for (...) {
// create `operation` AFHTTPRequestOperation however you want and add it to some queue
// but just make sure to designate the completion operation dependency
[completionOperation addDependency:operation];
}
// now that all the other operations have been queued, you can now add the completion operation to whatever queue you want
[[NSOperationQueue mainQueue] addOperation:completionOperation];
我需要在服务器上创建一个实体,然后将几张图片上传到服务器。
所以首先阻止显示成功在服务器上创建实体然后我开始循环上传 10 张图片,但是应用程序不会在最后 10 张图片上传后发送通知,所以 'i' 变量可以是10 甚至不是订单中的 10。我不确定,但似乎块中的迭代不正确。所以我只想确保这 10 张图片已上传,然后调用发送通知。
所以我跳过了一些块参数和失败选项,我用于获取要上传的图像的数组等。只需将我的块作为在“{”之后显示成功调用的示例。
// success first block
block1
{
// cycle from 0 to 10
for (NSInteger i = 0; i <=10; i++)
{
// success upload image to the server block
block2
{
// if I did 10 uploads I need to send notification.
if (i == 10)
{
// send notification here when last block returned success....
}
}
}
}
您可以使用如下派发组。
// success first block
block1
{
dispatch_group_t group = dispatch_group_create();
// cycle from 0 to 10
__block NSUInteger successCount = 0;
for (NSInteger i = 0; i <=10; i++)
{
dispatch_group_enter(group);
// upload image to the server block
successOrErrorBlock
{
if (success)
successCount++;
dispatch_group_leave(group);
}
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
if (successCount == 10) {
// send notification here when last block returned success....
}
});
}
我在异步调用多个块时遵循的模式是创建待办事项列表(数组)并递归执行该列表,如下所示:
// say this is our asynch operation. presume that someParameter fully
// describes the operation, like a file to be uploaded
- (void)performSomeAsynchOperationDefinedBy:(id)someParameter completion:(void (^)(BOOL, NSError *))completion {
// this could wrap any operation, like anything from AFNetworking
}
- (void)doOperationsWithParameters:(NSArray *)parameters completion:(void (^)(BOOL, NSError *))completion {
if (!parameters.count) return completion(YES, nil);
id nextParameter = someParameters[0];
NSArray *remainingParameters = [parameters subarrayWithRange:NSMakeRange(1, parameters.count-1)];
[self performSomeAsynchOperationDefinedBy:nextParameter completion:^(BOOL success, NSError *error)) {
if (!error) {
[self doManyOperations:remainingParameters completion:completion];
} else {
completion(NO, error);
}
}];
}
现在,要执行多个操作,请将参数放在一个数组中,例如:
NSArray *parameters = @[@"filename0", @"filename1", ...];
[self doOperationsWithParameters:parameters completion:(BOOL success, NSError *error) {
NSLog(@"ta-da!");
}];
上面的变体在每次递归之前和之后调用进度块(具有进度百分比 initialCount/remainingCount
)应该直接从提供的示例开始。
另一种变体是将参数数组和完成块都包装在一个 NSObject 中,因此可以使用 performSelector:
进行递归调用,这样做的好处是不会结束堆栈在长递归上。
如果您正在创建一堆 AFHTTPRequestOperation
对象,那么最合乎逻辑的方法是创建一个完成操作并使其依赖于请求操作:
NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
// code to be run when the operations are all done should go here
}];
for (...) {
// create `operation` AFHTTPRequestOperation however you want and add it to some queue
// but just make sure to designate the completion operation dependency
[completionOperation addDependency:operation];
}
// now that all the other operations have been queued, you can now add the completion operation to whatever queue you want
[[NSOperationQueue mainQueue] addOperation:completionOperation];