Tous les produits
Search
Centre de documentation

ApsaraVideo VOD:Stratégie de cycle de vie du lecteur

Dernière mise à jour :Sep 11, 2026

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

acquirePlayer obtient une instance de lecteur. La stratégie décide s'il faut créer une nouvelle instance ou en réutiliser une existante.

Recyclage d'instance

recyclePlayer:force: recycle une instance. La stratégie décide s'il faut la détruire ou la conserver.

Nettoyage des ressources

clear nettoie toutes les instances de lecteur détenues par la stratégie et restaure l'état initial.

Préchargement

preloadWithCount: pré-crée des instances dans le pool pour réduire le TTFF (@optional).

Liaison d'ID

acquirePlayerWithUniqueId: obtient une instance via un ID métier unique (@optional).

Injection de fabrique

setupWithFactory: injecte une fabrique de lecteur. Cette méthode est appelée automatiquement par AliPlayerController.

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

DefaultLifecycleStrategy

Crée une nouvelle instance à chaque fois. La détruit immédiatement après utilisation.

Lecture standard

Stratégie de pool de réutilisation

ReusePoolLifecycleStrategy

Maintient un pool inactif. Réutilise d'abord les instances du pool.

Liste de vidéos courtes

Politique de liaison d'ID

IdScopedPoolLifecycleStrategy

Maintient une instance distincte pour chaque uniqueId. Évince les instances selon un algorithme Least Recently Used (LRU).

Préchargement vidéo

Stratégie singleton

SingletonLifecycleStrategy

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];
Remarque

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];
Remarque

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];
}
Remarque

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 de force .

  • 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

acquirePlayer

Crée une nouvelle instance via la fabrique

recyclePlayer:force:

Détruit directement l'instance, quelle que soit la valeur de force

clear

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

acquirePlayer

Obtient d'abord une instance du pool inactif. Si le pool est vide, crée une nouvelle instance via la fabrique.

recyclePlayer:force:NO

Arrête la lecture et renvoie l'instance au pool inactif. Si le pool est plein, détruit l'instance.

recyclePlayer:force:YES

Détruit immédiatement l'instance.

clear

Détruit toutes les instances du pool inactif. Les instances actives ne sont pas affectées.

preloadWithCount:

Pré-crée des instances et les ajoute au pool inactif. Le nombre est limité par maxPoolSize .

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 uniqueId ré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

acquirePlayerWithUniqueId: (ID trouvé)

Renvoie l'instance existante et met à jour sa position dans l'ordre LRU.

acquirePlayerWithUniqueId: (ID non trouvé)

Obtient d'abord une instance de la file d'attente préchargée. Sinon, crée une nouvelle instance et la lie à l'ID.

recyclePlayer:uniqueId:force:NO

Arrête uniquement la lecture. L'instance reste dans la table de mappage et est évincée automatiquement par l'algorithme LRU.

recyclePlayer:uniqueId:force:YES

Supprime l'instance de la table de mappage et la détruit immédiatement.

clear

Nettoie les instances de la file d'attente préchargée et de la table de mappage.

preloadWithCount:

Crée des instances sans ID lié. Elles sont utilisées la première fois qu'un nouvel ID est obtenu.

Remarque

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.

  • clear est une opération sans effet. Elle ne détruit pas l'instance singleton. Vous devez la détruire explicitement en appelant recyclePlayer:force:YES .

  • Ne convient pas aux scénarios où plusieurs vidéos sont lues simultanément.

  • Plusieurs instances AliPlayerController ne peuvent pas détenir le lecteur simultanément. Cela provoquerait des conflits d'état.

Flux principal :

Opération

Comportement

acquirePlayer

Renvoie l'instance globale si elle existe. Sinon, la crée.

recyclePlayer:force:NO

Arrête uniquement la lecture. L'instance est conservée.

recyclePlayer:force:YES

Détruit l'instance globale.

clear

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
Remarque

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
Remarque

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

configure: Recyclage interne + acquisition

Automatique, aucune opération manuelle nécessaire

Destruction du contrôleur

La méthode destroy appelle en interne recyclePlayer:force:YES.

Complétion automatique

Sortie de page

Appelez [controller destroy] dans dealloc

Doit être appelé manuellement

Libération des ressources du pool

[strategy clear]

À 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 UIApplicationDidReceiveMemoryWarningNotification et appeler clear.

Définir une capacité de pool raisonnable

Chaque instance de lecteur utilise environ 35 Mo à 40 Mo de mémoire. Vous devez définir maxPoolSize en fonction des performances de l'appareil.

Libérer le pool inactif en arrière-plan

Vous pouvez appeler clear pour libérer les instances inactives lorsque l'application passe en arrière-plan.

Appeler destroy lors de la destruction de la page

Vous devez appeler [controller destroy] dans dealloc. Sinon, une fuite de mémoire se produira.

// 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 [controller destroy] dans dealloc

Éviter les fuites de mémoire

Nettoyage de la stratégie

Le dernier utilisateur appelle [strategy clear]

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 setupWithFactory:

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

PlayerLifecycleStrategy

Protocole de stratégie de cycle de vie. Définit les interfaces pour l'acquisition, le recyclage et la suppression des instances.

BaseLifecycleStrategy

Classe de base de stratégie. Fournit la gestion de l'usine et les méthodes de modèle createPlayer/destroyPlayer:.

PlayerFactory

Protocole d'usine de lecteur. Définit les interfaces pour la création et la destruction des instances.

DefaultPlayerFactory

Implémentation d'usine par défaut. Utilise le SDK Alibaba Cloud Player pour créer des instances.

MediaPlayer

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

DefaultLifecycleStrategy

[[... alloc] init]

—

ReusePoolLifecycleStrategy

[[... alloc] initWithMaxPoolSize:]

maxPoolSize, idleCount, activeCount

IdScopedPoolLifecycleStrategy

[[... alloc] initWithMaxPoolSize:]

maxPoolSize, poolCount

SingletonLifecycleStrategy

[... sharedInstance]

—

Méthodes PlayerLifecycleStrategy

Méthode

Obligatoire

Description

setupWithFactory:

Oui

Injecte l'usine de lecteur. Appelée automatiquement par le contrôleur.

acquirePlayer

Oui

Obtient une instance de lecteur.

recyclePlayer:force:

Oui

Recycle une instance de lecteur.

clear

Oui

Libère toutes les instances mises en cache.

preloadWithCount:

Non

Précharge des instances. Implémenté par ReusePool et IdScoped.

acquirePlayerWithUniqueId:

Non

Obtient une instance par uniqueId. Implémenté par IdScoped.

recyclePlayer:uniqueId:force:

Non

Recycle une instance par uniqueId. Implémenté par IdScoped.

Méthodes BaseLifecycleStrategy

Méthode/Propriété

Description

factory

L'usine de lecteur actuellement injectée (lecture seule).

setupWithFactory:

Injecte l'usine. Idempotent, seul le premier appel est effectif.

createPlayer

Crée une instance via l'usine avec une journalisation uniforme.

destroyPlayer:

Détruit une instance via l'usine avec une journalisation uniforme.

Description du paramètre force

Valeur de force

Comportement

Scénario

NO

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 configure:.

YES

Détruit l'instance immédiatement, quelle que soit la stratégie.

Destruction du contrôleur. Utilisé en interne dans destroy.

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.