La stratégie de cycle de vie du lecteur constitue une conception architecturale centrale d'AliPlayerKit. Elle unifie la gestion de la création, de la réutilisation, du recyclage et de la destruction des instances de lecteur. Cela permet une planification plus efficace des ressources et une optimisation des performances dans différents scénarios métier.
Introduction
Qu'est-ce qu'une stratégie de cycle de vie du lecteur ?
Une stratégie de cycle de vie du lecteur est un mécanisme architectural qui gère le cycle de vie des instances de lecteur. Elle définit les opérations fondamentales telles que l'obtention, le recyclage et la suppression des instances de lecteur. Cette approche découple la gestion des ressources du lecteur de votre logique métier.
Les différents scénarios métier présentent des exigences distinctes en matière de gestion des instances de lecteur :
|
Scénario |
Exigences |
Stratégie recommandée |
|
Lecture vidéo standard |
Simple et direct, aucune réutilisation nécessaire |
Par défaut |
|
Liste de vidéos courtes |
Changements fréquents, démarrage rapide requis |
ReusePool |
|
Préchargement vidéo |
Lie un ID à une instance, prend en charge le préchargement |
IdScopedPool |
|
Scénarios sensibles à la mémoire |
Instance globale unique, empreinte mémoire minimale |
Singleton |
Valeur principale
La gestion du cycle de vie du lecteur via un modèle de stratégie offre les avantages principaux suivants :
Découplage : Votre logique métier n'a pas besoin de traiter les détails liés à la création et à la destruction des instances de lecteur.
Flexibilité : Vous pouvez choisir différentes stratégies au moment de l'exécution sans modifier votre logique métier.
Extensibilité : Vous pouvez implémenter des politiques personnalisées pour répondre à des besoins métier spécifiques.
Observabilité : La gestion unifiée du cycle de vie simplifie la surveillance et le débogage.
Contexte de conception
La stratégie de cycle de vie du lecteur trouve son origine dans le pool de lecteurs multi-instances de la solution de dramatiques courtes d'Alibaba Cloud. Elle a été conçue pour répondre aux exigences strictes en matière de temps jusqu'à la première image (TTFF), de fluidité lors des changements et de contrôle de la mémoire dans les flux à défilement rapide. AliPlayerKit abstrait cette pratique sous la forme d'un modèle de stratégie afin de créer une architecture plus générale et flexible pour la gestion du cycle de vie du lecteur.
Fonctionnalités
Capacités principales
|
Capacité |
description |
|
Obtention d'instance |
|
|
Recyclage d'instance |
|
|
Nettoyage des ressources |
|
|
Préchargement |
|
|
Liaison d'ID |
|
|
Injection de fabrique |
|
Stratégies intégrées
AliPlayerKit fournit quatre stratégies de cycle de vie du lecteur intégrées :
|
Stratégie |
Nom de classe |
description |
Scénarios |
|
Stratégie par défaut |
|
Crée une nouvelle instance à chaque fois. La détruit immédiatement après utilisation. |
Lecture standard |
|
Stratégie de pool de réutilisation |
|
Maintient un pool inactif. Réutilise d'abord les instances du pool. |
Liste de vidéos courtes |
|
Politique de liaison d'ID |
|
Maintient une instance distincte pour chaque uniqueId. Évince les instances selon un algorithme Least Recently Used (LRU). |
Préchargement vidéo |
|
Stratégie singleton |
|
Une instance globale unique. Toutes les demandes d'obtention renvoient la même instance. |
Lecture en liste, scénarios sensibles à la mémoire |
Couches d'architecture
┌──────────────────────────────────────────────────────────────┐
│ AliPlayerController │
│ initWithLifecycleStrategy: Injects strategy │
│ configure: Internally calls recycle(old) + acquire(new) │
│ destroy: Internally calls recycle(player, force:YES) │
├──────────────────────────────────────────────────────────────┤
│ PlayerLifecycleStrategy protocol │
│ setupWithFactory: / acquirePlayer / recyclePlayer:force: │
│ clear / preloadWithCount: / acquirePlayerWithUniqueId: │
├──────────────────────────────────────────────────────────────┤
│ BaseLifecycleStrategy base class │
│ factory / createPlayer / destroyPlayer: │
├──────────┬──────────┬─────────────────┬──────────────────────┤
│ Default │ReusePool │ IdScopedPool │ Singleton │
│ New each time │ Pool reuse │ ID binding + LRU │ Global singleton │
└──────────┴──────────┴─────────────────┴──────────────────────┘
│ │
│ PlayerFactory protocol / DefaultPlayerFactory │
│ createPlayer / destroyPlayer: │
└──────────────────────────────────────────────────────────────┘
Utilisation
Utilisation de base — Stratégie par défaut
Il s'agit de la méthode la plus simple pour utiliser le lecteur. Aucune configuration supplémentaire n'est requise. AliPlayerController utilise DefaultLifecycleStrategy par défaut :
// Create a controller. The default strategy is used automatically.
AliPlayerController *controller = [[AliPlayerController alloc] init];
// Create the playback data.
VideoSource *source = [VideoSource urlSourceWithUrl:@"https://example.com/video.mp4"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
// Configure the controller and attach it to the player view.
[controller configure:model];
[self.playerView attach:controller];
Comportement de la stratégie par défaut : Une nouvelle instance est créée pour chaque appel à acquirePlayer . L'instance est détruite immédiatement à chaque appel à recyclePlayer:force: . Aucun pool n'est maintenu.
Stratégie de pool de réutilisation (scénario de vidéos courtes)
Cette stratégie convient aux scénarios impliquant des changements fréquents de vidéo, tels que les listes de vidéos courtes et les flux :
// 1. Create a reuse pool strategy with a maximum capacity of 3.
ReusePoolLifecycleStrategy *strategy =
[[ReusePoolLifecycleStrategy alloc] initWithMaxPoolSize:3];
// 2. Inject the strategy when creating the controller.
AliPlayerController *controller =
[[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// 3. Configure and use the controller as normal.
VideoSource *source = [VideoSource urlSourceWithUrl:@"https://example.com/video.mp4"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
[controller configure:model];
[self.playerView attach:controller];
AliPlayerController appelle automatiquement [strategy setupWithFactory:[AliPlayerKit playerFactory]] pour injecter la fabrique par défaut lors de l'appel à initWithLifecycleStrategy:. Vous n'avez pas besoin d'initialiser la stratégie manuellement.
Stratégie limitée par ID (scénario de préchargement)
Cette stratégie convient aux scénarios nécessitant un préchargement et un basculement entre plusieurs vidéos. Le même uniqueId renvoie toujours la même instance :
// 1. Create an ID-scoped strategy with a maximum capacity of 3.
IdScopedPoolLifecycleStrategy *strategy =
[[IdScopedPoolLifecycleStrategy alloc] initWithMaxPoolSize:3];
// 2. Inject the strategy when creating the controller.
AliPlayerController *controller =
[[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// 3. Usage — configure internally binds the ID using VideoSource.uniqueId.
VideoSource *source = [VideoSource vidAuthSourceWithVid:@"your_video_id"
playAuth:@"your_play_auth"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
[controller configure:model];
[self.playerView attach:controller];
Stratégie singleton (scénario de lecture en liste)
Cette stratégie utilise une instance globale unique. Tous les contrôleurs partagent le même lecteur :
// Get the singleton strategy. dispatch_once ensures it is globally unique.
SingletonLifecycleStrategy *strategy =
[SingletonLifecycleStrategy sharedInstance];
// Create the controller.
AliPlayerController *controller =
[[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// All controllers that use this strategy share the same player instance.
VideoSource *source = [VideoSource urlSourceWithUrl:@"https://example.com/video.mp4"];
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:source];
[controller configure:model];
[self.playerView attach:controller];
Lors de l'utilisation de la stratégie singleton, plusieurs instances AliPlayerController ne peuvent pas détenir le lecteur simultanément. Cela provoquerait des conflits d'état. La méthode init de SingletonLifecycleStrategy est marquée comme NS_UNAVAILABLE . Vous ne pouvez obtenir l'instance que via +sharedInstance .
Référence de scénario : Lecture en liste
ScenePlaylistViewController présente un exemple complet d'utilisation de SingletonLifecycleStrategy pour implémenter une lecture continue :
// Initialize the player lifecycle strategy.
self.lifecycleStrategy = [SingletonLifecycleStrategy sharedInstance];
// Create the controller and inject the strategy.
self.currentController = [[AliPlayerController alloc]
initWithLifecycleStrategy:self.lifecycleStrategy];
// Register a notification for playback completion to trigger autoplay for the next video.
[self.currentController addNotificationDelegate:self];
// Configure the data and attach the controller. Playback starts automatically after attachment.
AliPlayerModel *model = [[AliPlayerModel alloc] initWithVideoSource:videoSource];
[self.currentController configure:model];
[self.playerView attach:self.currentController];
// PlayerNotificationDelegate callback — Autoplay the next video after playback completes.
- (void)playerDidCompletion {
[self playNextVideo];
}
Dans un scénario de lecture en liste, SingletonLifecycleStrategy réutilise l'instance du lecteur. Cela évite la surcharge de performance liée à la création et à la destruction fréquentes. Lorsque vous changez de vidéo, configure: exécute automatiquement recycle(old instance) + acquire(new instance) . Vous n'avez pas besoin de gérer manuellement le cycle de vie du lecteur.
Détails des stratégies
DefaultLifecycleStrategy
Il s'agit de la stratégie la plus simple. Elle équivaut au comportement original avant l'introduction des stratégies de cycle de vie.
@interface DefaultLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
@end
Fonctionnalités :
Sans état. Crée une nouvelle instance via la fabrique pour chaque appel à
acquirePlayer.Détruit directement l'instance pour chaque appel à
recyclePlayer:force:, quelle que soit la valeur deforce.Utilisation mémoire la plus faible (libération après utilisation).
Convient à la plupart des scénarios de lecture standard.
Flux principal :
|
Opération |
Comportement |
|
|
Crée une nouvelle instance via la fabrique |
|
|
Détruit directement l'instance, quelle que soit la valeur de |
|
|
Aucune opération (ne maintient pas de pool) |
ReusePoolLifecycleStrategy
Cette stratégie repose sur le modèle de pool d'objets. Elle maintient un pool inactif et une liste active.
@interface ReusePoolLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
/// The maximum capacity of the pool. Default is 3. If this capacity is exceeded, recycle will destroy the instance directly.
@property (nonatomic, assign) NSInteger maxPoolSize;
/// The number of idle players currently in the pool.
@property (nonatomic, assign, readonly) NSInteger idleCount;
/// The number of active players that have been acquired but not yet recycled.
@property (nonatomic, assign, readonly) NSInteger activeCount;
- (instancetype)initWithMaxPoolSize:(NSInteger)maxPoolSize NS_DESIGNATED_INITIALIZER;
@end
Fonctionnalités :
Réutilise d'abord les instances du pool inactif pour réduire la surcharge d'initialisation du lecteur.
Prend en charge
preloadWithCount:pour pré-remplir le pool.La capacité du pool est contrôlée par
maxPoolSize.Toutes les méthodes sont thread-safe.
Convient aux listes de vidéos courtes et aux scénarios de flux.
Flux principal :
|
Opération |
Comportement |
|
|
Obtient d'abord une instance du pool inactif. Si le pool est vide, crée une nouvelle instance via la fabrique. |
|
|
Arrête la lecture et renvoie l'instance au pool inactif. Si le pool est plein, détruit l'instance. |
|
|
Détruit immédiatement l'instance. |
|
|
Détruit toutes les instances du pool inactif. Les instances actives ne sont pas affectées. |
|
|
Pré-crée des instances et les ajoute au pool inactif. Le nombre est limité par |
IdScopedPoolLifecycleStrategy
Cette stratégie maintient une instance de lecteur distincte pour chaque uniqueId . Le même uniqueId renvoie toujours la même instance. Elle utilise un mécanisme Least Recently Used (LRU) pour contrôler le nombre d'instances.
@interface IdScopedPoolLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
/// The maximum capacity of the pool. Default is 3. When exceeded, the least recently used instance is automatically evicted by the LRU algorithm.
/// If you change this value and the new value is less than the current number of instances, excess instances are immediately evicted in LRU order.
@property (nonatomic, assign) NSInteger maxPoolSize;
/// The number of player instances in the current mapping table (both active and idle).
@property (nonatomic, assign, readonly) NSInteger poolCount;
- (instancetype)initWithMaxPoolSize:(NSInteger)maxPoolSize NS_DESIGNATED_INITIALIZER;
@end
Fonctionnalités :
Liaison d'ID. Le même
uniqueIdréutilise toujours la même instance.Le mécanisme d'éviction LRU nettoie automatiquement les instances les moins récemment utilisées.
Prend en charge
preloadWithCount:pour pré-créer des instances non liées.Toutes les méthodes sont thread-safe.
La conception repose sur le mécanisme de gestion LRU du pool de lecteurs multi-instances de la solution de dramatiques courtes d'Alibaba Cloud.
Convient au préchargement vidéo et aux scénarios de basculement entre plusieurs vidéos.
Flux principal :
|
Opération |
Comportement |
|
|
Renvoie l'instance existante et met à jour sa position dans l'ordre LRU. |
|
|
Obtient d'abord une instance de la file d'attente préchargée. Sinon, crée une nouvelle instance et la lie à l'ID. |
|
|
Arrête uniquement la lecture. L'instance reste dans la table de mappage et est évincée automatiquement par l'algorithme LRU. |
|
|
Supprime l'instance de la table de mappage et la détruit immédiatement. |
|
|
Nettoie les instances de la file d'attente préchargée et de la table de mappage. |
|
|
Crée des instances sans ID lié. Elles sont utilisées la première fois qu'un nouvel ID est obtenu. |
Si une stratégie implémente la méthode acquirePlayerWithUniqueId: , AliPlayerController l'appelle à la place de acquirePlayer . Cela permet la liaison d'ID via VideoSource.uniqueId . De même, recyclePlayer:uniqueId:force: est appelé de préférence à recyclePlayer:force: .
SingletonLifecycleStrategy
Cette stratégie maintient une instance de lecteur globale unique. Elle est implémentée comme un véritable modèle singleton utilisant dispatch_once .
@interface SingletonLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
/// Gets the globally shared singleton strategy instance.
+ (instancetype)sharedInstance;
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
@end
Fonctionnalités :
Globalement unique. Tous les contrôleurs utilisant cette stratégie partagent la même instance de lecteur.
Utilisation mémoire la plus faible.
clearest une opération sans effet. Elle ne détruit pas l'instance singleton. Vous devez la détruire explicitement en appelantrecyclePlayer:force:YES.Ne convient pas aux scénarios où plusieurs vidéos sont lues simultanément.
Plusieurs instances
AliPlayerControllerne peuvent pas détenir le lecteur simultanément. Cela provoquerait des conflits d'état.
Flux principal :
|
Opération |
Comportement |
|
|
Renvoie l'instance globale si elle existe. Sinon, la crée. |
|
|
Arrête uniquement la lecture. L'instance est conservée. |
|
|
Détruit l'instance globale. |
|
|
Opération sans effet (ne détruit pas l'instance singleton). |
Tableau comparatif des stratégies
|
Stratégie |
Comportement d'obtention |
Comportement de recyclage (force:NO) |
Scénarios |
TTFF |
Thread safety |
|
Par défaut |
Nouveau à chaque fois |
Destruction immédiate |
Lecture standard |
Lent |
— |
|
ReusePool |
Obtention depuis le pool / Création nouvelle |
Retour au pool / Destruction si plein |
Liste de vidéos courtes |
Rapide |
Oui |
|
IdScoped |
ID trouvé / Pré-rempli / Création nouvelle |
Conservation dans la table de mappage / Éviction par LRU |
Préchargement |
Le plus rapide |
Oui |
|
Singleton |
Création unique |
Arrêt de la lecture uniquement |
Lecture en liste |
Moyen |
— |
Développement personnalisé
Protocole de stratégie (PlayerLifecycleStrategy)
Toutes les stratégies de cycle de vie sont conformes au protocole PlayerLifecycleStrategy :
@protocol PlayerLifecycleStrategy <NSObject>
@required
/// Injects the player factory. Called automatically by AliPlayerController.
- (void)setupWithFactory:(id<PlayerFactory>)factory;
/// Gets a player instance. The strategy decides whether to create or reuse one.
- (id<MediaPlayer>)acquirePlayer;
/// Recycles a player instance. force:YES forces destruction. force:NO lets the strategy decide.
- (void)recyclePlayer:(nullable id<MediaPlayer>)player force:(BOOL)force;
/// Releases all player instances held by the strategy and restores the initial state.
- (void)clear;
@optional
/// Preloads a specified number of player instances into the pool.
- (void)preloadWithCount:(NSInteger)count;
/// Gets a player instance by a unique business ID. Implemented only by IdScopedPoolLifecycleStrategy.
- (id<MediaPlayer>)acquirePlayerWithUniqueId:(NSString *)uniqueId;
/// Recycles a player instance by a unique business ID. Implemented only by IdScopedPoolLifecycleStrategy.
- (void)recyclePlayer:(nullable id<MediaPlayer>)player
uniqueId:(NSString *)uniqueId
force:(BOOL)force;
@end
La méthode setupWithFactory: est appelée automatiquement par AliPlayerController lors de l'appel à initWithLifecycleStrategy: pour injecter l'instance d'usine renvoyée par [AliPlayerKit playerFactory]. Les développeurs n'ont généralement pas besoin d'appeler cette méthode manuellement. Pour précharger des instances avant de créer un contrôleur, vous pouvez appeler manuellement setupWithFactory: puis preloadWithCount:.
Classe de base de stratégie (BaseLifecycleStrategy)
BaseLifecycleStrategy est la classe de base partagée pour toutes les stratégies intégrées. Elle fournit la gestion de l'usine et des méthodes de modèle :
@interface BaseLifecycleStrategy : NSObject
/// The currently injected player factory (read-only).
@property (nonatomic, strong, readonly) id<PlayerFactory> factory;
/// Injects the player factory. This is idempotent. It only takes effect on the first call. Subsequent calls are ignored and a warning is logged.
- (void)setupWithFactory:(id<PlayerFactory>)factory;
/// Creates a new player instance through the factory. Child classes should call this method instead of calling the factory directly.
- (id<MediaPlayer>)createPlayer;
/// Destroys a player instance through the factory. Child classes should call this method instead of calling the factory directly.
- (void)destroyPlayer:(nullable id<MediaPlayer>)player;
@end
BaseLifecycleStrategy elle-même ne déclare pas la conformité au protocole PlayerLifecycleStrategy. Les classes enfants doivent déclarer leur conformité et implémenter des méthodes telles que acquirePlayer, recyclePlayer:force: et clear. Les classes enfants doivent utiliser les méthodes de modèle createPlayer et destroyPlayer: pour opérer sur les instances de lecteur plutôt que d'appeler directement l'factory. Cela garantit que les opérations sont journalisées de manière uniforme.
Usine de lecteur (PlayerFactory)
Le protocole PlayerFactory définit l'interface pour la création et la destruction des instances de lecteur :
@protocol PlayerFactory <NSObject>
/// Creates a player instance. Each call creates a new instance in the PlayerStateIdle state.
- (id<MediaPlayer>)createPlayer;
/// Destroys a player instance. This releases all resources. If the instance is nil, only a warning is logged.
- (void)destroyPlayer:(nullable id<MediaPlayer>)player;
@end
Le framework inclut l'usine intégrée DefaultPlayerFactory, qui utilise le SDK Alibaba Cloud Player (AliPlayer) pour créer des instances standard. Vous pouvez la remplacer par une usine personnalisée en utilisant [AliPlayerKit setPlayerFactory:].
Exemple de stratégie personnalisée
L'exemple suivant montre une politique de cache simple basée sur le mappage d'ID :
@interface MyCacheLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
@end
@implementation MyCacheLifecycleStrategy {
NSMutableDictionary<NSString *, id<MediaPlayer>> *_playerMap;
}
- (instancetype)init {
self = [super init];
if (self) {
_playerMap = [NSMutableDictionary dictionary];
}
return self;
}
#pragma mark - PlayerLifecycleStrategy
- (id<MediaPlayer>)acquirePlayer {
return [self createPlayer];
}
- (id<MediaPlayer>)acquirePlayerWithUniqueId:(NSString *)uniqueId {
id<MediaPlayer> player = _playerMap[uniqueId];
if (!player) {
player = [self createPlayer];
_playerMap[uniqueId] = player;
}
return player;
}
- (void)recyclePlayer:(id<MediaPlayer>)player
uniqueId:(NSString *)uniqueId
force:(BOOL)force {
if (!player) return;
if (force) {
[_playerMap removeObjectForKey:uniqueId];
[self destroyPlayer:player];
} else {
[player stop];
}
}
- (void)recyclePlayer:(id<MediaPlayer>)player force:(BOOL)force {
if (!player) return;
[self destroyPlayer:player];
}
- (void)clear {
for (id<MediaPlayer> player in _playerMap.allValues) {
[self destroyPlayer:player];
}
[_playerMap removeAllObjects];
}
@end
Enregistrement et utilisation :
MyCacheLifecycleStrategy *strategy = [[MyCacheLifecycleStrategy alloc] init];
AliPlayerController *controller =
[[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// The controller automatically calls [strategy setupWithFactory:...] to inject the factory.
Flux de cycle de vie
Flux d'interaction entre le contrôleur et la stratégie
AliPlayerController initialization
↓
initWithLifecycleStrategy: → Saves strategy reference
↓ → Automatically calls [strategy setupWithFactory:[AliPlayerKit playerFactory]]
↓
[controller configure:model]
↓
├── Has player? → [strategy recyclePlayer:old instance force:NO]
↓
├── Does strategy implement acquirePlayerWithUniqueId:?
│ ├── YES → [strategy acquirePlayerWithUniqueId:source.uniqueId]
│ └── NO → [strategy acquirePlayer]
↓
├── [player setDataSource:model]
├── [player prepare]
└── autoPlay ? → [player start]
↓
Switch video source → [controller configure:newModel]
↓ → recycle(old) + acquire(new) + setDataSource + prepare
↓
[controller destroy]
↓
├── [strategy recyclePlayer:player force:YES]
└── Controller release
Quand nettoyer les ressources de la stratégie
|
Moment |
Opération |
Description |
|
Changement de vidéo |
|
Automatique, aucune opération manuelle nécessaire |
|
Destruction du contrôleur |
La méthode |
Complétion automatique |
|
Sortie de page |
Appelez |
Doit être appelé manuellement |
|
Libération des ressources du pool |
|
À appeler selon les besoins (par exemple, en cas d'avertissement de mémoire) |
Bonnes pratiques
Guide de sélection de stratégie
|
Scénario |
Stratégie recommandée |
Raison |
|
Page produit vidéo normale |
Default |
Simple et direct. Les ressources sont libérées lorsque la page est détruite. |
|
Liste défilante verticale de vidéos courtes |
ReusePool |
La réutilisation des instances réduit la surcharge de création et améliore la fluidité du défilement. |
|
Préchargement vidéo / Lecture instantanée |
IdScoped |
La liaison par ID et le préchargement permettent un démarrage extrêmement rapide. |
|
Lecture continue en liste |
Singleton |
Une seule instance globale réduit le nombre d'initialisations. |
|
Appareils bas de gamme / Faible mémoire |
Singleton |
Instance globale unique pour une empreinte mémoire minimale. |
|
Podcast / Lecture audio |
Singleton |
Un scénario de flux audio unique ne nécessite pas plusieurs instances. |
Recommandations de gestion de la mémoire
|
Recommandation |
Description |
|
Écouter les avertissements de mémoire |
Les stratégies basées sur un pool doivent écouter |
|
Définir une capacité de pool raisonnable |
Chaque instance de lecteur utilise environ 35 Mo à 40 Mo de mémoire. Vous devez définir |
|
Libérer le pool inactif en arrière-plan |
Vous pouvez appeler |
|
Appeler destroy lors de la destruction de la page |
Vous devez appeler |
// Listen for memory warnings to release pool resources.
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(handleMemoryWarning:)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
- (void)handleMemoryWarning:(NSNotification *)notification {
[self.lifecycleStrategy clear];
}
Gestion du cycle de vie de la page
@interface MyViewController ()
@property (nonatomic, strong) AliPlayerView *playerView;
@property (nonatomic, strong) AliPlayerController *controller;
@property (nonatomic, strong) id<PlayerLifecycleStrategy> lifecycleStrategy;
@end
@implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.lifecycleStrategy = [[ReusePoolLifecycleStrategy alloc] initWithMaxPoolSize:3];
self.controller = [[AliPlayerController alloc]
initWithLifecycleStrategy:self.lifecycleStrategy];
// ... configure + attach
}
- (void)dealloc {
// Required: Destroy the controller.
if (_controller) {
[_controller destroy];
}
// Optional: If this page is the last user of the strategy, release the pool resources.
if (_lifecycleStrategy) {
[_lifecycleStrategy clear];
}
}
@end
Remarques
|
Scénario |
Pratique recommandée |
Raison |
|
Destruction de page |
Appelez |
Éviter les fuites de mémoire |
|
Nettoyage de la stratégie |
Le dernier utilisateur appelle |
Libérer les instances inactives dans le pool |
|
Stratégie Singleton |
Ne pas permettre à plusieurs contrôleurs de détenir le lecteur simultanément |
Éviter les conflits d'état |
|
Injection d'usine |
N'appelez pas manuellement |
Le contrôleur l'injecte automatiquement et la méthode est idempotente (seul le premier appel est effectif). |
|
Préchargement |
À appeler après la création du contrôleur |
L'usine est injectée automatiquement lors de la création du contrôleur. |
Erreurs courantes
// ✗ Incorrect: Forgetting to destroy the controller in dealloc.
- (void)dealloc {
[self.playerView detach];
// [_controller destroy] is not called, causing a memory leak.
}
// ✓ Correct: Destroy the controller and clean up the strategy as needed.
- (void)dealloc {
if (_controller) {
[_controller destroy];
}
if (_lifecycleStrategy) {
[_lifecycleStrategy clear];
}
}
// ✗ Incorrect: Holding multiple controllers at the same time with a singleton strategy.
SingletonLifecycleStrategy *strategy = [SingletonLifecycleStrategy sharedInstance];
AliPlayerController *controller1 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
AliPlayerController *controller2 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// controller1 and controller2 share the same player instance, causing a state conflict.
// ✓ Correct: Ensure only one controller uses the singleton strategy at a time.
[controller1 destroy];
AliPlayerController *controller2 = [[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// ✗ Incorrect: Trying to alloc init SingletonLifecycleStrategy.
SingletonLifecycleStrategy *strategy = [[SingletonLifecycleStrategy alloc] init]; // Compile error.
// ✓ Correct: Get the instance through sharedInstance.
SingletonLifecycleStrategy *strategy = [SingletonLifecycleStrategy sharedInstance];
Référence API
Classes et protocoles principaux
|
Protocole / Classe |
Description |
|
|
Protocole de stratégie de cycle de vie. Définit les interfaces pour l'acquisition, le recyclage et la suppression des instances. |
|
|
Classe de base de stratégie. Fournit la gestion de l'usine et les méthodes de modèle createPlayer/destroyPlayer:. |
|
|
Protocole d'usine de lecteur. Définit les interfaces pour la création et la destruction des instances. |
|
|
Implémentation d'usine par défaut. Utilise le SDK Alibaba Cloud Player pour créer des instances. |
|
|
Protocole de lecteur multimédia. Définit les interfaces pour le contrôle de lecture, les requêtes d'état, etc. |
Stratégies intégrées
|
Classe |
Méthode de création |
Propriétés clés |
|
|
|
— |
|
|
|
|
|
|
|
|
|
|
|
— |
Méthodes PlayerLifecycleStrategy
|
Méthode |
Obligatoire |
Description |
|
|
Oui |
Injecte l'usine de lecteur. Appelée automatiquement par le contrôleur. |
|
|
Oui |
Obtient une instance de lecteur. |
|
|
Oui |
Recycle une instance de lecteur. |
|
|
Oui |
Libère toutes les instances mises en cache. |
|
|
Non |
Précharge des instances. Implémenté par ReusePool et IdScoped. |
|
|
Non |
Obtient une instance par uniqueId. Implémenté par IdScoped. |
|
|
Non |
Recycle une instance par uniqueId. Implémenté par IdScoped. |
Méthodes BaseLifecycleStrategy
|
Méthode/Propriété |
Description |
|
|
L'usine de lecteur actuellement injectée (lecture seule). |
|
|
Injecte l'usine. Idempotent, seul le premier appel est effectif. |
|
|
Crée une instance via l'usine avec une journalisation uniforme. |
|
|
Détruit une instance via l'usine avec une journalisation uniforme. |
Description du paramètre force
|
Valeur de force |
Comportement |
Scénario |
|
|
La stratégie décide si elle doit retourner l'instance au pool ou simplement arrêter la lecture. |
Changement de vidéo normal. Utilisé en interne dans |
|
|
Détruit l'instance immédiatement, quelle que soit la stratégie. |
Destruction du contrôleur. Utilisé en interne dans |
Description de uniqueId
uniqueId est une propriété d'identifiant métier unique sur VideoSource utilisée pour distinguer différentes sources vidéo. Différentes stratégies l'utilisent de différentes manières :
|
Stratégie |
Objectif de uniqueId |
|
Default |
Non utilisé |
|
ReusePool |
Non utilisé |
|
IdScoped |
Identifiant principal. Le même uniqueId renvoie toujours la même instance. |
|
Singleton |
Non utilisé |
Référence d'exemple
Le module PlayerKitUsages/UsageLifecycleStrategy fournit un exemple complet d'utilisation des stratégies de cycle de vie du lecteur. Il illustre le basculement entre les quatre stratégies intégrées (Default, ReusePool, Singleton et IdScopedPool). Il montre également le comportement de réutilisation des instances (NEW/REUSED/HIT) pour la lecture multi-sources et le flux de nettoyage des ressources pour les stratégies et les contrôleurs.