A estratégia de ciclo de vida do player é um componente arquitetônico central do AliPlayerKit. Ela unifica o gerenciamento da criação, reutilização, reciclagem e destruição de instâncias do player, permitindo agendamento de recursos mais eficiente e otimização de desempenho em diferentes cenários de negócios.
Introdução
O que é uma estratégia de ciclo de vida do player?
A estratégia de ciclo de vida do player é um mecanismo arquitetônico que gerencia o ciclo de vida das instâncias do player. Ela define operações essenciais como aquisição, reciclagem e limpeza dessas instâncias, desacoplando o gerenciamento de recursos do player da lógica de negócios.
Cenários de negócios distintos apresentam requisitos diferentes para o gerenciamento de instâncias do player:
|
Cenário |
Requisitos |
Estratégia recomendada |
|
Reprodução de vídeo normal |
Simples e direta, sem necessidade de reutilização |
Default |
|
Lista de vídeos curtos |
Troca frequente, exige inicialização rápida |
ReusePool |
|
Pré-carregamento de vídeo |
Vincula um ID a uma instância, suporta pré-carregamento |
IdScopedPool |
|
Cenários sensíveis à memória |
Instância global única, uso mínimo de memória |
Singleton |
Valor principal
Gerenciar o ciclo de vida do player com um padrão de estratégia oferece as seguintes vantagens fundamentais:
Desacoplamento: A lógica de negócios não precisa lidar com os detalhes de criação e destruição de instâncias do player.
Flexibilidade: Escolha estratégias diferentes em tempo de execução sem alterar a lógica de negócios.
Extensibilidade: Implemente políticas personalizadas para atender a necessidades específicas de negócios.
Observabilidade: O gerenciamento unificado do ciclo de vida simplifica o monitoramento e a depuração.
Contexto do design
A estratégia de ciclo de vida do player teve origem no pool de players multi-instância da solução de minisséries da Alibaba Cloud. Foi projetada para atender a requisitos rigorosos de tempo até o primeiro quadro (TTFF), transição suave e controle de memória em feeds de rolagem rápida. O AliPlayerKit abstrai essa prática em um padrão de estratégia para criar uma arquitetura mais geral e flexível para gerenciar o ciclo de vida do player.
Recursos
Capacidades principais
|
Capacidade |
Descrição |
|
Aquisição de instância |
|
|
Reciclagem de instância |
|
|
Limpeza de recursos |
|
|
Pré-carregamento |
|
|
Vinculação de ID |
|
|
Injeção de fábrica |
|
Estratégias integradas
O AliPlayerKit fornece quatro estratégias de ciclo de vida do player integradas:
|
Estratégia |
Nome da classe |
Descrição |
Cenários |
|
Estratégia padrão |
|
Cria uma nova instância a cada vez. Destrói-a imediatamente após o uso. |
Reprodução normal |
|
Estratégia de pool de reutilização |
|
Mantém um pool ocioso. Prioriza a reutilização de instâncias do pool. |
Lista de vídeos curtos |
|
Política de vinculação de ID |
|
Mantém uma instância separada para cada uniqueId. Remove instâncias usando um algoritmo LRU (Least Recently Used). |
Pré-carregamento de vídeo |
|
Estratégia singleton |
|
Uma única instância global. Todas as solicitações de aquisição retornam a mesma instância. |
Reprodução em lista, cenários sensíveis à memória |
Camadas de arquitetura
┌──────────────────────────────────────────────────────────────┐
│ 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: │
└──────────────────────────────────────────────────────────────┘
Uso
Uso básico — Estratégia padrão
Esta é a maneira mais simples de usar o player. Nenhuma configuração extra é necessária. O AliPlayerController usa a DefaultLifecycleStrategy por padrão:
// 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];
Comportamento da estratégia padrão: Uma nova instância é criada para cada chamada de acquirePlayer. A instância é destruída imediatamente a cada chamada de recyclePlayer:force:. Nenhum pool é mantido.
Estratégia de pool de reutilização (cenário de vídeo curto)
Esta estratégia é adequada para cenários com troca frequente de vídeos, como listas e feeds de vídeos curtos:
// 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];
O AliPlayerController chama automaticamente [strategy setupWithFactory:[AliPlayerKit playerFactory]] para injetar a fábrica padrão durante a chamada initWithLifecycleStrategy:. Você não precisa inicializar a estratégia manualmente.
Estratégia com escopo de ID (cenário de pré-carregamento)
Esta estratégia é ideal para cenários que exigem pré-carregamento e alternância entre vários vídeos. O mesmo uniqueId sempre retorna a mesma instância:
// 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];
Estratégia singleton (cenário de reprodução em lista)
Esta estratégia utiliza uma única instância global. Todos os controladores compartilham o mesmo player:
// 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];
Ao usar a estratégia singleton, várias instâncias de AliPlayerController não podem manter o player simultaneamente. Isso causaria conflitos de estado. O método init da SingletonLifecycleStrategy está marcado como NS_UNAVAILABLE. Obtenha a instância apenas por meio de +sharedInstance.
Referência de cenário: Reprodução em lista
O ScenePlaylistViewController apresenta um exemplo completo de uso da SingletonLifecycleStrategy para implementar reprodução contínua:
// 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];
}
Em um cenário de reprodução em lista, a SingletonLifecycleStrategy reutiliza a instância do player. Isso evita a sobrecarga de desempenho decorrente da criação e destruição frequentes. Ao trocar de vídeo, o método configure: executa automaticamente recycle(old instance) + acquire(new instance). Não é necessário gerenciar o ciclo de vida do player manualmente.
Detalhes da estratégia
DefaultLifecycleStrategy
Esta é a estratégia mais simples. Equivale ao comportamento original antes da introdução das estratégias de ciclo de vida.
@interface DefaultLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
@end
Características:
Sem estado. Cria uma nova instância por meio da fábrica para cada chamada de
acquirePlayer.Destrói a instância diretamente a cada chamada de
recyclePlayer:force:, independentemente do valor deforce.Menor uso de memória (liberada após o uso).
Indicada para a maioria dos cenários de reprodução padrão.
Fluxo principal:
|
Operação |
Comportamento |
|
|
Cria uma nova instância por meio da fábrica |
|
|
Destrói a instância diretamente, independentemente do valor de |
|
|
Nenhuma operação (não mantém um pool) |
ReusePoolLifecycleStrategy
Esta estratégia baseia-se no padrão de pool de objetos. Mantém um pool ocioso e uma lista ativa.
@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
Características:
Prioriza a reutilização de instâncias do pool ocioso para reduzir a sobrecarga de inicialização do player.
Suporta
preloadWithCount:para preencher previamente o pool.A capacidade do pool é controlada por
maxPoolSize.Todos os métodos são thread-safe.
Projetada para listas de vídeos curtos e cenários de feed.
Fluxo principal:
|
Operação |
Comportamento |
|
|
Obtém uma instância do pool ocioso primeiro. Se o pool estiver vazio, cria uma nova instância por meio da fábrica. |
|
|
Interrompe a reprodução e devolve a instância ao pool ocioso. Se o pool estiver cheio, destrói a instância. |
|
|
Destrói a instância imediatamente. |
|
|
Destrói todas as instâncias no pool ocioso. As instâncias ativas não são afetadas. |
|
|
Pré-cria instâncias e as adiciona ao pool ocioso. A quantidade é limitada por |
IdScopedPoolLifecycleStrategy
Esta estratégia mantém uma instância de player separada para cada uniqueId. O mesmo uniqueId sempre retorna a mesma instância. Utiliza um mecanismo LRU (Least Recently Used) para controlar o número de instâncias.
@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
Características:
Vinculação de ID. O mesmo
uniqueIdsempre reutiliza a mesma instância.O mecanismo de remoção LRU limpa automaticamente as instâncias usadas menos recentemente.
Suporta
preloadWithCount:para pré-criar instâncias não vinculadas.Todos os métodos são thread-safe.
O design baseia-se no mecanismo de gerenciamento LRU do pool de players multi-instância na solução de minisséries da Alibaba Cloud.
Recomendada para pré-carregamento de vídeo e cenários de alternância entre múltiplos vídeos.
Fluxo principal:
|
Operação |
Comportamento |
|
|
Retorna a instância existente e atualiza sua posição na ordem LRU. |
|
|
Obtém uma instância da fila de pré-carregamento primeiro. Caso contrário, cria uma nova instância e a vincula ao ID. |
|
|
Apenas interrompe a reprodução. A instância permanece na tabela de mapeamento e é removida automaticamente pelo algoritmo LRU. |
|
|
Remove a instância da tabela de mapeamento e a destrói imediatamente. |
|
|
Limpa as instâncias na fila de pré-carregamento e na tabela de mapeamento. |
|
|
Cria instâncias sem um ID vinculado. Estas são usadas na primeira vez que um novo ID é adquirido. |
Se uma estratégia implementar o método acquirePlayerWithUniqueId:, o AliPlayerController o chamará em vez de acquirePlayer. Isso permite a vinculação de ID por meio de VideoSource.uniqueId. Da mesma forma, recyclePlayer:uniqueId:force: é chamado preferencialmente em relação a recyclePlayer:force:.
SingletonLifecycleStrategy
Esta estratégia mantém uma única instância global do player. É implementada como um verdadeiro padrão singleton usando dispatch_once.
@interface SingletonLifecycleStrategy : BaseLifecycleStrategy <PlayerLifecycleStrategy>
/// Gets the globally shared singleton strategy instance.
+ (instancetype)sharedInstance;
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
@end
Características:
Globalmente única. Todos os controladores que usam esta estratégia compartilham a mesma instância do player.
Menor consumo de memória.
clearé uma operação nula. Não destrói a instância singleton. Destrua-a explicitamente chamandorecyclePlayer:force:YES.Não recomendada para cenários onde vários vídeos são reproduzidos simultaneamente.
Várias instâncias de
AliPlayerControllernão podem manter o player simultaneamente. Isso causaria conflitos de estado.
Fluxo principal:
|
Operação |
Comportamento |
|
|
Retorna a instância global se ela existir. Caso contrário, cria-a. |
|
|
Apenas interrompe a reprodução. A instância é retida. |
|
|
Destrói a instância global. |
|
|
Operação nula (não destrói a instância singleton). |
Tabela comparativa de estratégias
|
Estratégia |
Comportamento de aquisição |
Comportamento de reciclagem (force:NO) |
Cenários |
TTFF |
Thread safety |
|
Default |
Novo para cada item |
Destruição imediata |
Reprodução normal |
Lento |
— |
|
ReusePool |
Obter do pool / Criar novo |
Devolver ao pool / Destruir se cheio |
Lista de vídeos curtos |
Rápido |
Sim |
|
IdScoped |
ID encontrado / Pré-preenchido / Criar novo |
Manter na tabela de mapeamento / Remover por LRU |
Pré-carregamento |
Mais rápido |
Sim |
|
Singleton |
Criar apenas uma vez |
Apenas interromper reprodução |
Reprodução em lista |
Médio |
— |
Desenvolvimento personalizado
Protocolo de estratégia (PlayerLifecycleStrategy)
Todas as estratégias de ciclo de vida estão em conformidade com o protocolo 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
O AliPlayerController chama setupWithFactory: automaticamente durante a chamada initWithLifecycleStrategy: para injetar a instância de fábrica retornada por [AliPlayerKit playerFactory]. Geralmente, os desenvolvedores não precisam chamar este método manualmente. Para pré-carregar instâncias antes de criar um controlador, chame manualmente setupWithFactory: e depois preloadWithCount:.
Classe base de estratégia (BaseLifecycleStrategy)
A BaseLifecycleStrategy é a classe base compartilhada para todas as estratégias integradas. Fornece gerenciamento de fábrica e métodos de modelo:
@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
A própria BaseLifecycleStrategy não declara conformidade com o protocolo PlayerLifecycleStrategy. As classes filhas devem declarar conformidade e implementar métodos como acquirePlayer, recyclePlayer:force: e clear. As classes filhas devem usar os métodos de modelo createPlayer e destroyPlayer: para operar em instâncias do player, em vez de chamar a factory diretamente. Isso garante que as operações sejam registradas uniformemente.
Fábrica de players (PlayerFactory)
O protocolo PlayerFactory define a interface para criar e destruir instâncias do player:
@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
O framework inclui a DefaultPlayerFactory integrada, que usa o Alibaba Cloud Player SDK (AliPlayer) para criar instâncias padrão. Substitua-a por uma fábrica personalizada usando [AliPlayerKit setPlayerFactory:].
Exemplo de estratégia personalizada
O exemplo a seguir mostra uma política de cache simples baseada em mapeamento de 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
Registro e uso:
MyCacheLifecycleStrategy *strategy = [[MyCacheLifecycleStrategy alloc] init];
AliPlayerController *controller =
[[AliPlayerController alloc] initWithLifecycleStrategy:strategy];
// The controller automatically calls [strategy setupWithFactory:...] to inject the factory.
Fluxo do ciclo de vida
Fluxo de interação entre controlador e estratégia
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
Quando limpar recursos da estratégia
|
Momento |
Operação |
Descrição |
|
Troca de vídeo |
|
Automático, nenhuma operação manual necessária |
|
Destruição do controlador |
O método |
Automático |
|
Saída da página |
Chame |
Deve ser chamado manualmente |
|
Liberação de recursos do pool |
|
Chame conforme necessário (por exemplo, em um aviso de memória) |
Melhores práticas
Guia de seleção de estratégia
|
Cenário |
Estratégia recomendada |
Motivo |
|
Página de produto de vídeo normal |
Default |
Simples e direta. Os recursos são liberados quando a página é destruída. |
|
Lista de rolagem vertical de vídeos curtos |
ReusePool |
A reutilização de instâncias reduz a sobrecarga de criação e melhora a suavidade da rolagem. |
|
Pré-carregamento de vídeo / Reprodução instantânea |
IdScoped |
A vinculação de ID e o pré-carregamento permitem uma inicialização extremamente rápida. |
|
Reprodução contínua em lista |
Singleton |
Uma única instância global reduz o número de inicializações. |
|
Dispositivos básicos / Pouca memória |
Singleton |
Instância global única para uso mínimo de memória. |
|
Podcast / Reprodução de áudio |
Singleton |
Um cenário de fluxo de áudio único não requer múltiplas instâncias. |
Recomendações de gerenciamento de memória
|
Recomendação |
Descrição |
|
Ouça avisos de memória |
Estratégias baseadas em pool devem ouvir |
|
Defina uma capacidade de pool razoável |
Cada instância do player usa cerca de 35 MB a 40 MB de memória. Defina |
|
Libere o pool ocioso em segundo plano |
Chame |
|
Chame destroy quando a página for destruída |
Chame |
// 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];
}
Gerenciamento do ciclo de vida da página
@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
Observações
|
Cenário |
Prática recomendada |
Motivo |
|
Destruição de página |
Chame |
Evita vazamentos de memória |
|
Limpeza de estratégia |
O último usuário chama |
Libera instâncias ociosas no pool |
|
Estratégia singleton |
Não permita que vários controladores mantenham o player simultaneamente |
Evita conflitos de estado |
|
Injeção de fábrica |
Não chame |
O controlador a injeta automaticamente e o método é idempotente (apenas a primeira chamada tem efeito). |
|
Pré-carregamento |
Chame após a criação do controlador |
A fábrica é injetada automaticamente quando o controlador é criado. |
Erros comuns
// ✗ 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];
Referência da API
Classes e protocolos principais
|
Protocolo / Classe |
Descrição |
|
|
Protocolo de estratégia de ciclo de vida. Define interfaces para adquirir, reciclar e limpar instâncias. |
|
|
Classe base de estratégia. Fornece gerenciamento de fábrica e métodos de modelo createPlayer/destroyPlayer:. |
|
|
Protocolo de fábrica de players. Define interfaces para criar e destruir instâncias. |
|
|
Implementação de fábrica padrão. Usa o Alibaba Cloud Player SDK para criar instâncias. |
|
|
Protocolo de media player. Define interfaces para controle de reprodução, consultas de status e muito mais. |
Estratégias integradas
|
Classe |
Método de criação |
Propriedades principais |
|
|
|
— |
|
|
|
|
|
|
|
|
|
|
|
— |
Métodos de PlayerLifecycleStrategy
|
Método |
Obrigatório |
Descrição |
|
|
Sim |
Injeta a fábrica de players. Chamado automaticamente pelo controlador. |
|
|
Sim |
Obtém uma instância do player. |
|
|
Sim |
Recicla uma instância do player. |
|
|
Sim |
Libera todas as instâncias em cache. |
|
|
Não |
Pré-carrega instâncias. Implementado por ReusePool e IdScoped. |
|
|
Não |
Obtém uma instância por uniqueId. Implementado por IdScoped. |
|
|
Não |
Recicla uma instância por uniqueId. Implementado por IdScoped. |
Métodos de BaseLifecycleStrategy
|
Método/Propriedade |
Descrição |
|
|
A fábrica de players atualmente injetada (somente leitura). |
|
|
Injeta a fábrica. Idempotente, apenas a primeira chamada tem efeito. |
|
|
Cria uma instância por meio da fábrica com registro uniforme. |
|
|
Destrói uma instância por meio da fábrica com registro uniforme. |
Descrição do parâmetro force
|
Valor de force |
Comportamento |
Cenário |
|
|
A estratégia decide se devolve a instância ao pool ou apenas interrompe a reprodução. |
Troca normal de vídeo. Usado dentro de |
|
|
Destrói a instância imediatamente, independentemente da estratégia. |
Destruição do controlador. Usado dentro de |
Descrição de uniqueId
uniqueId é uma propriedade de identificador de negócio exclusivo em VideoSource usada para distinguir diferentes fontes de vídeo. Diferentes estratégias o utilizam de maneiras distintas:
|
Estratégia |
Finalidade do uniqueId |
|
Default |
Não utilizado |
|
ReusePool |
Não utilizado |
|
IdScoped |
Identificador principal. O mesmo uniqueId sempre retorna a mesma instância. |
|
Singleton |
Não utilizado |
Referência de exemplo
O módulo PlayerKitUsages/UsageLifecycleStrategy fornece um exemplo completo de como usar estratégias de ciclo de vida do player. Demonstra a alternância entre as quatro estratégias integradas (Default, ReusePool, Singleton e IdScopedPool). Mostra também o comportamento de reutilização de instância (NEW/REUSED/HIT) para reprodução de múltiplas fontes e o fluxo de limpeza de recursos para estratégias e controladores.