目标 -C 回调不适用于不幸的后台崩溃

Posted

技术标签:

【中文标题】目标 -C 回调不适用于不幸的后台崩溃【英文标题】:Objective -C Call back doesnot working with an unfortunate background crash 【发布时间】:2017-07-04 06:14:38 【问题描述】:

我正在尝试从完成块发送回调侦听器。我在自定义UIView 中启动回调,并从父视图控制器(UIView 子视图)执行完成块。这是代码...(我不想使用委托)

ViewController.h中的回调声明

typedef void(^ExportCompletion)(BOOL success, NSURL* url);
@property (nonatomic, copy) ExportCompletion exportBlock;
-(void) exportCompletionBlock:(ExportCompletion)callback;

ViewController.m回调的初始化和实现

-(void) exportCompletionBlock:(ExportCompletion)callback

    if (callback) 
        self.exportBlock = callback;
    

来自 Completion 处理程序的实现(调用)(它也在 ViewController.m 中)

-(void)blockAlertAppear:(float)progress
    if(EXPORT_SESSION_COMPLETED!=progress)
        doing something...
    if(EXPORT_SESSION_COMPLETED==progress)
        self.exportBlock(YES, mCompositor.url);
    

在uicustomview中回调操作...CustomUIView.m

-(void) initUIView
    [(ViewController*)[[self superview] nextResponder] exportCompletionBlock:^(BOOL success, NSURL *url) 
    if (success) 
        doing something...
    
];

我可以在这里使用委托,但我想使用回调。我对回电很陌生。我想知道为什么会发生崩溃(它来自后台 - 所以不明白原因)以及如何优化代码?

【问题讨论】:

【参考方案1】:

如果[(ViewController*)[[self superview] nextResponder] 返回 nil,这可能是崩溃的原因。但是使用 [[self superview] nextResponder] 并不是一个好习惯。让我们尝试一个完成处理程序。我试着给你举个例子。

ViewController.h中的回调声明

typedef void(^ExportCompletion)(BOOL success, NSURL* url);
@property (nonatomic, copy) ExportCompletion exportBlock;

在您的视图控制器中 ViewController.m 无需分配 exportCompletionBlock 。只需在需要时分配即可。例如,您的 CustomView 中有一个委托,该委托在 ViewController.m 中实现。

在你的CustomUIView.h 添加这个

typedef void(^ExportCompletion)(BOOL success, NSURL* url);

@protocol CustomUIViewDelegate <NSObject>
- (void) startExport:(ExportCompletion)completionBlock;
@end

从您想要的事件中呼叫您的代表,例如

在你的CustomUIView.m

- (IBAction)ButtonTapped:(UIButton *)sender 
    [self.delegate startExport:^(BOOL success, NSURL *url) 
        if (success) 
            doing something...
        
    ];

在您的 ViewCOntroller.m 代码中保持不变,但对幻灯片进行了一些修改

和原来一样

-(void)blockAlertAppear:(float)progress
    if(EXPORT_SESSION_COMPLETED!=progress)
        doing something...
    if(EXPORT_SESSION_COMPLETED==progress)
        self.exportBlock(YES, mCompositor.url);
    

ViewCOntroller.m中实现委托

- (void) startExport:(ExportCompletion)completionBlock
    self.exportBlock = completionBlock;
    the thing you want to do...

这是一种处理完成块的方法。不知道对你有多大帮助。这只是实现代码的一种新方法。 & 它可以帮助您防止使用[[self superview] nextResponder] 视图依赖。

【讨论】:

【参考方案2】:

为什么你的最后一个方法调用“initUIView”???如果您在未添加到超级视图([viewController.view addsubview:yourView])之前初始化新视图,则视图没有 Superview。我认为,如果您在 NSLog 中打印 [(ViewController*)[[self superview] nextResponder] ,您将看到 Nil。这就是崩溃的原因

【讨论】:

以上是关于目标 -C 回调不适用于不幸的后台崩溃的主要内容,如果未能解决你的问题,请参考以下文章

CocoaPods 不适用于框架目标

VSCode“files.exclude”不适用于特定目标

SSH 代理转发不适用于所有 SSH 目标机器[关闭]

AWS CloudFormation:Application Load Balancer 的目标组不适用于多个 EC2 实例

Sklearn fbeta_score默认平均参数不适用于多类目标变量

控制台目标日志记录不适用于 NUnit 测试用例源提供程序中调用的方法