如何避免iOS编程中的代码
}];
}];
}];
});
以下是我的代码中的一个场景:
(void)my_function {
dispatch_async(dispatch_get_main_queue(), ^{
NSManagedObjectContext *childContext = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];
childContext.parentContext = self.managedObjectContext;
[childContext performBlock:^{
[self.operationManager POST:URL parameters:nil block:^(AFHTTPRequestOperation *operation, id responseObject) {
//Do something
[childContext performBlock:^{
//Do something
}];
}];
}];
});
}
为什么我问这个问题:
答案 0 :(得分:1)
如果可能(即当你的块没有依赖于使用它们的上下文或局部变量时),你可以在函数之外或函数开头声明块,将它们存储在变量中,然后在需要时按名称使用它们。
您将避免一些嵌套,因为所有开始/结束块括号都将处于同一级别。
CrystalReportViewer1.SeparatePages = false;
这就是主意。您必须小心捕获的变量和上下文的范围,并查看(在这种情况下)是否可以在声明块时实例化NSManagedObjectContext,而不是在主队列上执行第一个(块1)时。 / p>
答案 1 :(得分:0)
这是我想出的(这个特定的例子):
- (void)my_function { // I'd use camelCase
[self.operationManager POST:URL parameters:nil block:^(AFHTTPRequestOperation *operation, id responseObject) {
NSManagedObjectContext *childContext = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease]; // autorelease is gone with ARC
childContext.parentContext = self.managedObjectContext;
[childContext performBlock:^{
// Do something
}];
}];
}
或强>
- (void)my_function { // I'd use camelCase
[self.operationManager POST:URL parameters:nil block:^(AFHTTPRequestOperation *operation, id responseObject) {
[self another_function:responseObject];
// Uncomment if you really need to use the main thread
//[self performSelectorOnMainThread:@selector(another_function:) withObject:responseObject waitUntilDone:NO];
}];
}
- (void)another_function:(id)responseObject { // I'd use camelCase
NSManagedObjectContext *childContext = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease]; // autorelease is gone with ARC
childContext.parentContext = self.managedObjectContext;
[childContext performBlock:^{
// Do something with the 'responseObject'
}];
}
丢弃" dispatch_get_main_queue()" - 我认为你不必在主线程上使用主线程上下文,如果你想在Core Data中执行操作,你必须在主线程上。
提取了self.operationManager的POST,因为它不必在上下文的performBlock中。
然后在self.operationManager的块内做任何你需要做的事。
答案 2 :(得分:0)
我不想讨论这些代码是否可读。我认为这是一个熟悉积木的问题。
但是,有时您希望重新线性化代码执行,因为代码中的嵌套块是一个接一个地执行的。如果你有一个期望块参数的方法的同步双胞胎,只需使用它。如果没有,你可以自己构建它。
让我们拥有方法的异步版本:
@interface MyClass : …
- (void)doSomethingInBackgroundCompletion:…;
@end
具有典型用法:
…
[receiver doSomethingInBackgroundCompletion:
^(id result)
{
// Do Something with result
…
}
…
您可以使用信号量线性化它。只需在类别中的同步版本:
@interface MyClass (Linearization)
- (id)doSomethingInBackgroundAndWait;
@end
@implementation MyClass (Linearization)
- (id)doeSomethingInBackgroundAndWait
{
dispatch_semaphore_t done = dispatch_semaphore_create(0);
__block id finally;
[receiver doSomethingInBackgroundCompletion:
^(id result)
{
finally = result;
dispatch_semaphore_signal(done);
}
dispatch_semaphore_wait(done);
dispatch_semaphore_release(done);
return result;
}
@end
现在您可以使用该方法同步:
…
id result = [receiver doSomethingInBackgroundAndWait];
// Do Something with result
…
我不说这应该是一种常见的模式。在大多数情况下,熟悉块是更好的方法。