You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Native中Realm实例频繁提示已关闭问题求助

React-Native中Realm实例频繁触发「已关闭」错误的解决方案

问题背景

在React-Native应用中使用Realm时,组件内通过createRealmContext可正常使用,但为了在组件外部操作Realm,创建了单例模式的独立Realm实例,却仍偶尔出现Error: Cannot access realm that has been closed.错误,该错误基本发生在调用RealmInstance.objects<Article>(Article.schema.name)时。

当前配置代码

schema.ts

import 'react-native-get-random-values';
import { Realm } from '@realm/react';
import { Account } from './Account';
import { Article } from './Article';

export const realmSchema = [
    Account.schema,
    Article.schema
]

export const realmConfig: Realm.Configuration = {
    schema: realmSchema
}

RealmContext.ts

import { createRealmContext } from "@realm/react";
import { realmConfig } from "./schema";

export const realmContext = createRealmContext(realmConfig);

RealmInstance.ts(单例实现)

import { Realm } from '@realm/react';
import { realmConfig } from "./schema";

class RealmInstance {
    private static _instance: RealmInstance;
    public realm!: Realm;
    private constructor() {}

    public static getInstance(): RealmInstance {
        if (!RealmInstance._instance) {
            RealmInstance._instance = new RealmInstance();
            RealmInstance._instance.realm = new Realm(realmConfig);
        }

        return RealmInstance._instance;
    }
}

export default RealmInstance.getInstance().realm;

错误原因分析

  • GC回收风险:单例中的Realm实例若未被持续引用,在Hermes引擎下可能被判定为无引用对象而被垃圾回收关闭,尤其是组件外部使用场景下,没有@realm/react Context那样的持续引用绑定机制。
  • 双实例冲突:同时存在createRealmContext和手动单例创建的两个Realm实例,可能导致内部连接状态被意外干扰,比如一个实例关闭时影响另一个的可用性。
  • 初始化时机问题:单例实例若在应用启动早期初始化,但后续无持续引用持有,也可能被GC回收。

解决方案

方案1:给单例添加自动重连与全局引用

修改RealmInstance.ts,增加实例状态检查,关闭时自动重连,同时用全局变量持有实例避免被GC回收:

import { Realm } from '@realm/react';
import { realmConfig } from "./schema";

class RealmInstance {
    private static _instance: RealmInstance;
    private _realm?: Realm;
    private constructor() {}

    public static getInstance(): RealmInstance {
        if (!RealmInstance._instance) {
            RealmInstance._instance = new RealmInstance();
        }
        return RealmInstance._instance;
    }

    public get realm(): Realm {
        if (!this._realm || this._realm.isClosed) {
            this._realm = new Realm(realmConfig);
            // 全局引用持有,防止被GC回收
            (global as any).__RealmGlobalInstance = this._realm;
        }
        return this._realm;
    }
}

export default RealmInstance.getInstance().realm;

方案2:统一使用Realm Context实例(组件外部访问)

@realm/react支持在组件外部获取已初始化的实例,无需单独创建新实例:

  1. 确保根组件挂载RealmProvider:
import { realmContext } from './RealmContext';

const { RealmProvider } = realmContext;

function App() {
  return (
    <RealmProvider>
      {/* 你的导航、页面组件 */}
    </RealmProvider>
  );
}
  1. 创建工具函数获取实例:
import { Realm } from '@realm/react';
import { realmConfig } from "./schema";

export async function getRealmInstance(): Promise<Realm> {
  // 优先获取已打开的实例
  const openRealms = Realm.allInstances;
  if (openRealms.length > 0) {
    return openRealms[0];
  }
  // 无打开实例时重新初始化
  return await Realm.open(realmConfig);
}

方案3:手动维护实例生命周期

在应用启动时初始化实例,退出时才关闭,确保实例在整个应用周期内活跃:

// RealmInstance.ts
import { Realm } from '@realm/react';
import { realmConfig } from "./schema";

let realm: Realm;

export function initRealm() {
  if (!realm || realm.isClosed) {
    realm = new Realm(realmConfig);
  }
}

export function getRealm() {
  if (!realm || realm.isClosed) {
    throw new Error('Realm未初始化,请先调用initRealm');
  }
  return realm;
}

在根组件中初始化并管理生命周期:

import { useEffect } from 'react';
import { initRealm, getRealm } from './RealmInstance';

function App() {
  useEffect(() => {
    initRealm();
    // 应用退出时关闭实例
    return () => {
      const realm = getRealm();
      if (!realm.isClosed) {
        realm.close();
      }
    };
  }, []);

  return (
    // ...
  );
}

关键注意事项

  • 避免同时创建多个Realm实例,统一实例来源减少状态冲突。
  • 确保Realm实例被全局变量或持续存在的组件引用持有,降低GC回收概率。
  • 使用Realm对象前,优先检查isClosed状态,必要时重新打开实例。

内容的提问来源于stack exchange,提问作者LiohAu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 13:35:36