之前在StackOverFlow中这不是一个琐碎的问题,至少我没有找到类似的东西,当然我也googled并阅读了大多数排名较高的结果。

顺便说一句,如果这里的任何人对Objective C’块语法不满意,请访问此页面
http://fuckingblocksyntax.com
在抛出任何与块相关的问题之前。

我的问题的第一部分是:the background of declaration of block-parameter, as well as invoking a method which has a block-parameter ( in many cases, a completionBlock )

MyWorker类中的“ calleE-method”:
……

@implementation MyWorker
-(void) aWorkerMethodNeedsABlockInput: ((void)(^)( NSObject *, double )) blockParam
{
       NSObject *anObj=[[ NSObject alloc] init];
       double *aDouble;
       [self retrieveTimeConsumingResults: anObj withNumberOfTry: aDouble ];
       blockParam ( anObj, * aDouble );

}

@end


MyManager类中的“ calleR-method”:

@interface myManager()
@property (nonatomic) MyWorker * mWorker;
@property (nonatomic, copy)  (void)(^mBlockProperty)( NSObject *, double );
@end
@implementation MyManager
-(void) aManagerMethodWhoCallsWorkerWithCompletionHandler
{
    (void)(^ valBlock )( NSObject *, double ) = ^(void)( NSObject * realObj, double realDouble )
     {
                 [realObj performSelector:@SEL( aSelector) withObject: @(realDouble) afterDelay: aTimeInterval];
        } ;
   self.mBlockProperty=[valBlock copy];
   [self.mWorker aWorkerMethodNeedsABlockInput : self.mBlockProperty];

}

@end


在我们的自定义代码中,上述sudo代码是在存储属性中存储块,声明块参数以及在CALLEE中提供块参数的NORMAL方法。提供块定义,并在CALLER中“使用”块的参数。为了清楚起见,我以'void' returnType的形式写作。如果我做错了,请更正我的写作!

我的问题的第二部分:

的常规用法

    - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {
    NSLog(@"Handle events for background url session");

    self.backgroundSessionCompletionHandler = completionHandler;
}


然后再

- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
    WebAppDelegate *appDelegate = (WebAppDelegate *)[[UIApplication sharedApplication] delegate];
    if (appDelegate.backgroundSessionCompletionHandler) {
        void (^completionHandler)() = appDelegate.backgroundSessionCompletionHandler;
        appDelegate.backgroundSessionCompletionHandler = nil;

        completionHandler();
    }
    NSLog(@"All tasks are finished");
}


通过守护程序进行的后台回调在以上基于NSURLSession框架的模式中起作用,对吗?我做了很多次,在应用这种模式上没有问题。

我一直想知道的是:

当从块属性存储中调用该方法时,“ handleEventsForBackgroundURLSession:”方法的completionHandler参数的定义实际上是什么?
我从未见过任何样本/演示将任何代码块放入/复制到completionHandler ...,或者我想知道太多?

最佳答案

从块属性存储中调用该方法时,“ handleEventsForBackgroundURLSession:”方法的completionHandler参数的定义里面到底是什么? 我从未见过任何示例/演示,可以将任何代码块/复制到complementHandler中...或者我想知道太多?


如果我正确理解了您的问题,则您正在询问系统将哪些实现传递给UIApplicationDelegate方法application:handleEventsForBackgroundURLSession:completionHandler:的应用程序实现的块内。

application:handleEventsForBackgroundURLSession:completionHandler:由外部service process(间接)调用。当应用程序使用NSURLSession创建后台会话时,该会话由该系统服务管理。该服务执行实际的后台传输,并通知UIKit / Foundation,然后通过称为XPC的机制通知您的应用程序。 XPC已被MacOS开发人员广泛使用,但目前尚不能直接用于iOS应用程序-但是,iOS开发人员使用的许多API和服务实际上正在与XPC服务进行通信。

对于application:handleEventsForBackgroundURLSession:completionHandler:,传递给completionHandler参数的块是不透明的回调。后台传输服务需要知道您的应用程序何时完成了处理会话事件的操作。调用该块将通知服务,应用程序已完全处理了这组事件,并且守护程序可以继续运行。

该块是由系统创建和拥有的,因此,应用程序不应尝试对其进行修改或更改(除了复制该块,这是正确的选择!)。应用程序也不应提供自己的完成模块-开发人员提供的模块将无法通知完成转换的传输服务,除非它包装了传递给completionHandler:本身的模块。

iOS 7中引入了后台传输服务和NSURLSession。如果您正在编写第三方框架或库,则可以利用该服务非常有益,但是该框架必须提供一种处理任何后台会话事件的方法。它拥有。也许正因为如此,只有少数第三方库似乎支持后台传输。支持这一点并不难-库只需要一种方法来指示会话的所有权,以及一种采用完成块并处理事件的方法:

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {

    if ([someCloudFrameworkObject canHandleEventsForSessionWithIdentifier:identifier]){
        [someCloudFrameworkObject handleEventsForBackroundSessionWithIdentifier:identifier completionHandler:completionHandler];
    }
}

关于objective-c-blocks - handleEventsForBackgroundURLSession中的completionHandler定义:,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31780411/

10-13 04:34