uni-app Class方式写的uts插件导入到iOS离线打包工程中无法调用Class实例中的方法

uni-app Class方式写的uts插件导入到iOS离线打包工程中无法调用Class实例中的方法

开发环境 版本号 项目创建方式
Mac 15.5 CLI

产品分类:uniapp/App

PC开发环境操作系统:Mac

手机系统:iOS

手机系统版本号:iOS 18

手机厂商:苹果

手机机型:iPhone15 pro

页面类型:vue

vue版本:vue3

打包方式:离线

CLI版本号:3.0.0-4060620250520001


示例代码:

<h3>uts插件iOS</h3>
```javascript
export type CallA = {  
    onSuccess: (a: string) => void  
    onFail: (e: string) => void  
}  

export class LgTest {  

    private host : string = '';  
    private port : number = 0;  

    private callA : CallA | null = null  

    constructor(host: string, port: number) {  
        this.host = host  
        this.port = port  
    }  
    @UTSJS.keepAlive  
    public setCallA(call : CallA) : void {  
        this.callA = call  
    }  

    public mCallASuccess() : void {  
        if (this.callA !== null) {  
            this.callA!.onSuccess('调用了success')  
        }  
    }  

    public mCallAFail() : void {  
        if (this.callA !== null) {  
            this.callA!.onFail('调用了onFail')  
        }  
    }  

    public testA() : string {  
        return '232323testA23232323'  
    }  

}
```
<h3>uts使用代码</h3>
```javascript
import { LgTest } from '@/uni_modules/lg-test'  

let lgTestIns: LgTest | null = null  
const initTest = () => {  
    lgTestIns = new LgTest('192.168.0.0', 8080)  
}  
const setCall = () => {  
    if (lgTestIns) {  

        const callA = {  
            onSuccess: (a: string) => {  
                console.log('lgTestIns onSuccess回调了', a)  
            },  
            onFail: (e: string) => {  
                console.log('lgTestIns onFail回调了', e)  
            }  
        }  
        lgTestIns.setCallA(callA)  
    }  
}  
const callSuccess = () => {  
    if (lgTestIns) {  
        lgTestIns!.mCallASuccess()  
    }  
}  
const callFail = () => {  
    if (lgTestIns) {  
        lgTestIns!.mCallAFail()  
    }  
}  

const callTestA = () => {  
    if (lgTestIns) {  
        console.log('callTestA', lgTestIns!.testA())  
    }  
}
```

操作步骤:

调用initTest(),然后再调用setCall(),再调用callSuccess/callFail

预期结果:

控制台打印  “lgTestIns onSuccess回调了”、“lgTestIns onFail回调了”

实际结果:

<iOS离线应用会报错<Weex>[error]WXBridgeContext.mm:1323, jsLog: Error: method call failed: -[<NSCFNumber length]: unrecognized selector sent to instance 0x84dd6f027dbe993a ERROR

更多关于uni-app Class方式写的uts插件导入到iOS离线打包工程中无法调用Class实例中的方法的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

离线包使用的是4.66版本

更多关于uni-app Class方式写的uts插件导入到iOS离线打包工程中无法调用Class实例中的方法的实战教程也可以访问 https://www.itying.com/category-93-b0.html


https://nativesupport.dcloud.net.cn/AppDocs/usesdk/ios.html#utsconfig
看一下这两部分 需要你 1.添加UTS基础模块的依赖 2.制作UTS插件供主工程调用

这是一个典型的iOS离线打包中UTS插件内存管理问题。在iOS环境下,UTS Class实例如果没有正确保持引用,会被ARC机制提前释放。

问题分析:

  1. lgTestIns 在JavaScript环境中创建,但iOS原生层无法保持对该实例的强引用
  2. 当调用 setCallA() 后,原生对象可能已被释放,导致后续方法调用失败
  3. 错误信息中的 -[NSCFNumber length] 表明对象指针已指向错误的内存地址

解决方案:

方案一:使用单例模式保持实例引用

export class LgTest {
    private static instance: LgTest | null = null
    private host: string = ''
    private port: number = 0
    private callA: CallA | null = null

    static getInstance(host?: string, port?: number): LgTest {
        if (!LgTest.instance) {
            LgTest.instance = new LgTest(host || '', port || 0)
        }
        return LgTest.instance
    }

    private constructor(host: string, port: number) {
        this.host = host
        this.port = port
    }
}

方案二:确保全局强引用

// 在模块级别保持强引用
let globalInstance: LgTest | null = null

export const initTest = () => {
    globalInstance = new LgTest('192.168.0.0', 8080)
    return globalInstance
}

方案三:检查iOS离线打包配置 确保在iOS工程中正确配置了UTS插件依赖:

  1. 检查 manifest.json 中插件声明
  2. 验证iOS工程中是否包含了生成的UTS原生代码
  3. 确认iOS部署目标版本设置正确

推荐使用方案一,通过单例模式确保实例在应用生命周期内持续存在。同时建议在调用方法前添加空值检查:

const callSuccess = () => {  
    if (lgTestIns) {  
        lgTestIns.mCallASuccess()  
    } else {
        console.error('LgTest实例未初始化')
    }  
}
回到顶部