@@ -30,6 +30,7 @@ class RiveReactNativeView: RCTView, RivePlayerDelegate, RiveStateMachineDelegate
3030 var viewModel : RiveViewModel ?
3131 var dataBindingViewModelInstance : RiveDataBindingViewModel . Instance ?
3232 var cachedRiveFactory : RiveFactory ?
33+ var cachedRiveFile : RiveFile ?
3334 var previousReferencedAssets : NSDictionary ?
3435 var cachedFileAssets : [ String : RiveFileAsset ] = [ : ]
3536
@@ -158,6 +159,10 @@ class RiveReactNativeView: RCTView, RivePlayerDelegate, RiveStateMachineDelegate
158159 private func cleanupFileAssetCache( ) {
159160 cachedFileAssets. removeAll ( )
160161 cachedRiveFactory = nil
162+ // Note: We intentionally don't clear cachedRiveFile here to prevent a race condition
163+ // where async asset loaders (both custom and CDN) may still be using the factory
164+ // tied to the RiveFile. The cachedRiveFile will be replaced on next load or
165+ // released when this view is deallocated.
161166 }
162167
163168 override func layoutSubviews( ) {
@@ -331,6 +336,7 @@ class RiveReactNativeView: RCTView, RivePlayerDelegate, RiveStateMachineDelegate
331336 } else {
332337 updatedViewModel = RiveViewModel ( fileName: name, fit: convertFit ( fit) , alignment: convertAlignment ( alignment) , autoPlay: autoplay, artboardName: artboardName, customLoader: customLoader)
333338 }
339+ cachedRiveFile = updatedViewModel. riveModel? . riveFile
334340 warnForUnusedAssets ( )
335341
336342 updatedViewModel. layoutScaleFactor = layoutScaleFactor. doubleValue
@@ -355,6 +361,7 @@ class RiveReactNativeView: RCTView, RivePlayerDelegate, RiveStateMachineDelegate
355361 }
356362 do {
357363 let riveFile = try RiveFile ( data: data, loadCdn: true , customAssetLoader: customLoader)
364+ self . cachedRiveFile = riveFile
358365 let riveModel = RiveModel ( riveFile: riveFile)
359366 let fit = self . convertFit ( self . fit)
360367 let alignment = self . convertAlignment ( self . alignment)
@@ -514,25 +521,28 @@ class RiveReactNativeView: RCTView, RivePlayerDelegate, RiveStateMachineDelegate
514521 if ( data. isEmpty == true ) {
515522 return ;
516523 }
524+ let riveFileRef = cachedRiveFile
517525 DispatchQueue . global ( qos: . background) . async {
518- switch asset {
519- case let imageAsset as RiveImageAsset :
520- let decodedImage = factory. decodeImage ( data)
521- DispatchQueue . main. async {
522- imageAsset. renderImage ( decodedImage)
523- }
524- case let fontAsset as RiveFontAsset :
525- let decodedFont = factory. decodeFont ( data)
526- DispatchQueue . main. async {
527- fontAsset. font ( decodedFont)
528- }
529- case let audioAsset as RiveAudioAsset :
530- guard let decodedAudio = factory. decodeAudio ( data) else { return }
531- DispatchQueue . main. async {
532- audioAsset. audio ( decodedAudio)
526+ withExtendedLifetime ( riveFileRef) {
527+ switch asset {
528+ case let imageAsset as RiveImageAsset :
529+ let decodedImage = factory. decodeImage ( data)
530+ DispatchQueue . main. async {
531+ imageAsset. renderImage ( decodedImage)
532+ }
533+ case let fontAsset as RiveFontAsset :
534+ let decodedFont = factory. decodeFont ( data)
535+ DispatchQueue . main. async {
536+ fontAsset. font ( decodedFont)
537+ }
538+ case let audioAsset as RiveAudioAsset :
539+ guard let decodedAudio = factory. decodeAudio ( data) else { return }
540+ DispatchQueue . main. async {
541+ audioAsset. audio ( decodedAudio)
542+ }
543+ default :
544+ break
533545 }
534- default :
535- break
536546 }
537547 }
538548 }
0 commit comments