Marcar uma classe ou função como Sendable
garante que é seguro passar por limites simultâneos, tipos de valor são seguros, pois implementam cópia na gravação, etc., todos nós encontramos na documentação da linguagem Swift. Mas meu ponto é que Sendable
não promete que uma variável esteja livre de corridas de dados. Podemos ter corridas de dados mesmo em tipos de valor básicos, como Int
demonstrado no código abaixo. Então Sendable
não equivale a estar seguro de dados contra acesso/modificação simultânea, significa apenas que o valor é seguro para copiar em diferentes threads. Mas minha pergunta é qual problema isso resolve ou qual é a importância de ter Sendable
como uma construção então? Alguém pode explicar isso?
var num = 0
DispatchQueue.global(qos: .background).async {
for _ in 0..<100 {
num += 1
}
}
DispatchQueue.global(qos: .background).async {
for _ in 0..<100 {
num -= 1
}
}
Como você disse,
Sendable
permite que o compilador raciocine sobre se um valor é seguro para enviar através de domínios de simultaneidade. Isso é muito útil, porque você frequentemente escreve código que envia coisas através de domínios de simultaneidade. O compilador pode verificar se seu código é seguro ou não. SemSendable
, o compilador precisará proibir qualquer envio (excessivamente restritivo) ou permitir todos os envios (não seguro).De SE-0302 :
Um exemplo muito simples para demonstrar o quão útil
Sendable
é, é:Isso é seguro? Isso depende se os valores de
SomeType
são seguros para enviar ao nível superiorTask
. Se não for seguro enviar, você pode acabar com o valor deSomeType
sendo compartilhado entre oTask
e de onde quer que tenha vindo originalmente. Por exemplo, seSomeType
for uma classe com propriedades mutáveis, isso pode causar uma corrida:Se
SomeType
forSendable
, então o compilador pode permitir que o primeiro trecho de código seja compilado.Aqui está outro exemplo do SE-0302:
doThing
é isolado para o ator, e o ator poderia armazenar ostring
passado paradoThing
em uma de suas propriedades. E então você acaba com umNSMutableString
ser compartilhado entre o ator e quem quer que seja o dono original.Se usarmos
String
em vez deNSMutableString
, esse código é seguro porqueString
.Sendable
éString
cópia em gravação, então o ator que o modifica não afetará quem o possui originalmente.Objetivo do Sendable
Quando usar o Sendable
Exemplo: Tipo personalizado em conformidade com o Sendable
Exemplo: Usando Sendable com uma classe
Para uma classe estar em conformidade com Sendable, todas as suas propriedades armazenadas devem ser imutáveis ou estar em conformidade com Sendable. Além disso, a classe deve ser marcada como final.
Se uma propriedade for mutável, o compilador emitirá um erro, a menos que você tome medidas explícitas, como sincronizar o acesso ou garantir exclusividade.