uni-app iOS端扩展插件方法中调用NSNotificationCenter,app release环境下出现闪退,debug环境下正常

uni-app iOS端扩展插件方法中调用NSNotificationCenter,app release环境下出现闪退,debug环境下正常

产品分类

uniapp/App

PC开发环境

操作系统 版本号
Mac 14.3.1

手机系统

手机系统 手机系统版本号 手机厂商 手机机型
iOS iOS 11.0 苹果 iphone7

开发工具

工具名称 类型 版本号
HBuilderX 正式 4.01

页面类型

页面类型 vue版本
vue vue2

打包方式

离线

项目创建方式

HBuilderX

示例代码

AppDelegate.m 文件

// iOS 10 Support

(void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
    // Required
    NSDictionary * userInfo = response.notification.request.content.userInfo;
    if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
    }
    
    // 在处理通知点击逻辑的地方,   发送广播事件
    [[NSNotificationCenter defaultCenter] postNotificationName:@"JiguangBroadcastNotification" object:nil userInfo:userInfo];
    completionHandler();    // 系统要求执行这个方法
}

扩展插件文件CustomPushClickModule.m

// 通过宏 UNI_EXPORT_METHOD_SYNC 将同步方法暴露给 js 端
UNI_EXPORT_METHOD_SYNC(@selector(registerSyncClickHandler:))

/// 同步方法(注:同步方法会在 js 线程执行)
/// @param options js 端调用方法时传递的参数
```objc
(NSString *)registerSyncClickHandler:(NSDictionary *)options {
    //     [[EventBus sharedInstance] subscribeToEventWithName:@"GlobalEvent" handler:^(NSDictionary *)userInfo {
    //         NSString *message = userInfo[@"message"];
    //         NSLog(@"ClassA Received data: %@", message);
    //     }];
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(receiveBroadcastNotification:) name:@"JiguangBroadcastNotification" object:nil];
    
    // 同步返回参数给 js 端 注:只支持返回 String 或 NSDictionary (map) 类型
    return @"success";
}
(void)receiveBroadcastNotification:(NSNotification *)notification {
    // 处理接收到的通知
}

前端调用

var CustomPushClickModule = uni.requireNativePlugin("CustomPushClickModule")
CustomPushClickModule.registerSyncClickHandler({code:23})

## 操作步骤

### AppDelegate.m   文件
// iOS 10 Support  
```objc
(void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
    // Required
    NSDictionary * userInfo = response.notification.request.content.userInfo;
    if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
    }
    
    // 在处理通知点击逻辑的地方,   发送广播事件
    [[NSNotificationCenter defaultCenter] postNotificationName:@"JiguangBroadcastNotification" object:nil userInfo:userInfo];
    completionHandler();    // 系统要求执行这个方法
}

扩展插件文件CustomPushClickModule.m

// 通过宏 UNI_EXPORT_METHOD_SYNC 将同步方法暴露给 js 端
UNI_EXPORT_METHOD_SYNC(@selector(registerSyncClickHandler:))

/// 同步方法(注:同步方法会在 js 线程执行)
/// @param options js 端调用方法时传递的参数
```objc
(NSString *)registerSyncClickHandler:(NSDictionary *)options {
    //     [[EventBus sharedInstance] subscribeToEventWithName:@"GlobalEvent" handler:^(NSDictionary *)userInfo {
    //         NSString *message = userInfo[@"message"];
    //         NSLog(@"ClassA Received data: %@", message);
    //     }];
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(receiveBroadcastNotification:) name:@"JiguangBroadcastNotification" object:nil];
    
    // 同步返回参数给 js 端 注:只支持返回 String 或 NSDictionary (map) 类型
    return @"success";
}
(void)receiveBroadcastNotification:(NSNotification *)notification {
    // 处理接收到的通知
}

前端调用

onLaunch: function() {
    var CustomPushClickModule = uni.requireNativePlugin("CustomPushClickModule")
    CustomPushClickModule.registerSyncClickHandler({code:23})
}

## 预期结果
期望release版本下不闪退

## 实际结果
release版本下闪退

## bug描述
```javascript
iOS 端扩展插件方法中调用NSNotificationCenter广播注册事件,app release环境下出现闪退报错com.taobao.weex.bridge (9): signal SIGABRT,debug 环境下正常,不会出现闪退

更多关于uni-app iOS端扩展插件方法中调用NSNotificationCenter,app release环境下出现闪退,debug环境下正常的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于uni-app iOS端扩展插件方法中调用NSNotificationCenter,app release环境下出现闪退,debug环境下正常的实战教程也可以访问 https://www.itying.com/category-93-b0.html


在 Uni-App 的 iOS 扩展插件中,如果在 Release 环境下调用 NSNotificationCenter 出现闪退,而在 Debug 环境下正常工作,可能的原因有以下几种:

1. 未在主线程调用

NSNotificationCenter 的某些操作需要在主线程中执行。如果在非主线程中调用,可能会导致崩溃。你可以尝试将相关代码放在主线程中执行:

dispatch_async(dispatch_get_main_queue(), ^{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"YourNotificationName" object:nil];
});

2. 未正确初始化或释放对象

确保你在使用 NSNotificationCenter 之前,相关的对象已经正确初始化,并且在不需要时正确释放。特别是在 Release 环境下,内存管理的问题更容易暴露出来。

3. 通知名称不一致

检查你在发布和监听通知时,使用的通知名称是否一致。在 Release 环境下,编译器可能会优化掉某些字符串,导致通知名称不匹配。

4. 未正确移除观察者

如果你在某个对象中注册了通知观察者,确保在对象释放时移除观察者。否则,当通知发生时,可能会导致向已释放的对象发送消息,从而导致崩溃。

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

5. 编译器优化问题

Release 环境下,编译器会进行优化,可能会导致某些代码被优化掉或行为发生变化。你可以尝试关闭某些优化选项,看看问题是否依然存在。

6. 异常捕获

在 Release 环境下,某些异常可能被捕获并导致崩溃。你可以尝试在代码中添加异常捕获机制,以捕获潜在的异常:

@try {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"YourNotificationName" object:nil];
} @catch (NSException *exception) {
    NSLog(@"Exception: %@", exception);
}

7. 调试信息

在 Release 环境下,调试信息较少,可能会导致问题难以排查。你可以尝试在 Release 环境下启用更多的调试信息,或者使用 NSLog 输出更多信息。

8. 检查其他依赖

确保你的插件依赖的其他库或框架在 Release 环境下也能正常工作。有时候,某些库在 Release 环境下的行为可能与 Debug 环境下不同。

9. 使用 NSNotificationQueue

如果你需要更复杂的通知处理,可以尝试使用 NSNotificationQueue,它提供了更灵活的通知发布方式。

NSNotification *notification = [NSNotification notificationWithName:@"YourNotificationName" object:nil];
[[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP];
回到顶部