diff --git a/CHANGELOG.md b/CHANGELOG.md index 35eac1a54..b9231cdb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fixed a memory leak on iOS, caused by the wrapping ViewController that was keeping a strong reference to the THEOplayerRCTView. + ## [8.8.1] - 24-11-20 ### Fixed diff --git a/ios/THEOplayerRCTBridge.m b/ios/THEOplayerRCTBridge.m index 8f11cb4f6..5f795882c 100644 --- a/ios/THEOplayerRCTBridge.m +++ b/ios/THEOplayerRCTBridge.m @@ -51,8 +51,6 @@ @interface RCT_EXTERN_MODULE(THEOplayerRCTViewManager, RCTViewManager) RCT_EXPORT_VIEW_PROPERTY(onNativeCastEvent, RCTDirectEventBlock); -RCT_EXTERN_METHOD(destroy:(nonnull NSNumber *)node); - @end // ---------------------------------------------------------------------------- @@ -114,6 +112,8 @@ @interface RCT_EXTERN_REMAP_MODULE(THEORCTPlayerModule, THEOplayerRCTPlayerAPI, RCT_EXTERN_METHOD(setTextTrackStyle:(nonnull NSNumber *)node textTrackStyle:(NSDictionary)textTrackStyle) +RCT_EXTERN_METHOD(destroyPlayer:(nonnull NSNumber *)node); + @end // ---------------------------------------------------------------------------- diff --git a/ios/THEOplayerRCTPlayerAPI.swift b/ios/THEOplayerRCTPlayerAPI.swift index da57220f0..9d2eff052 100644 --- a/ios/THEOplayerRCTPlayerAPI.swift +++ b/ios/THEOplayerRCTPlayerAPI.swift @@ -356,5 +356,14 @@ class THEOplayerRCTPlayerAPI: NSObject, RCTBridgeModule { } } } + + @objc(destroyPlayer:) + func destroyPlayer(_ node: NSNumber) -> Void { + DispatchQueue.main.async { + if let theView = self.bridge.uiManager.view(forReactTag: node) as? THEOplayerRCTView { + theView.destroyPlayer() + } + } + } } diff --git a/ios/THEOplayerRCTView.swift b/ios/THEOplayerRCTView.swift index 4822d1eed..a3c0738da 100644 --- a/ios/THEOplayerRCTView.swift +++ b/ios/THEOplayerRCTView.swift @@ -139,7 +139,7 @@ public class THEOplayerRCTView: UIView { // MARK: - Destroy Player - func destroyPlayer() { + public func destroyPlayer() { self.mainEventHandler.destroy() self.textTrackEventHandler.destroy() self.mediaTrackEventHandler.destroy() @@ -154,6 +154,9 @@ public class THEOplayerRCTView: UIView { self.player?.destroy() self.player = nil if DEBUG_THEOPLAYER_INTERACTION { PrintUtils.printLog(logText: "[NATIVE] THEOplayer instance destroyed.") } + + self.theoPlayerViewController.view = nil + self.theoPlayerViewController.removeFromParent() } func processMetadataTracks(metadataTrackDescriptions: [TextTrackDescription]?) { diff --git a/src/api/player/THEOplayer.ts b/src/api/player/THEOplayer.ts index eab3f017f..4811c1313 100644 --- a/src/api/player/THEOplayer.ts +++ b/src/api/player/THEOplayer.ts @@ -72,6 +72,11 @@ export interface THEOplayer extends EventDispatcher { */ pause(): void; + /** + * destroy the player. + */ + destroy(): void; + /** * Whether the player is paused. */ diff --git a/src/internal/THEOplayerView.tsx b/src/internal/THEOplayerView.tsx index cb765d032..1dfaf696d 100644 --- a/src/internal/THEOplayerView.tsx +++ b/src/internal/THEOplayerView.tsx @@ -144,15 +144,9 @@ export class THEOplayerView extends PureComponent im } } + destroy(): void { + if (Platform.OS === 'ios') { + NativePlayerModule.destroyPlayer(this._view.nativeHandle); + } + } + public get version(): PlayerVersion { return this._playerVersion; }