Aprendendo o Objective-C e lendo o código de amostra, percebo que os objetos geralmente são criados usando este método:
SomeObject *myObject = [[SomeObject alloc] init];
ao invés de:
SomeObject *myObject = [SomeObject new];
Existe uma razão para isso, como eu li que eles são equivalentes?
objective-c
oop
willc2
fonte
fonte
Respostas:
Há várias razões aqui: http://macresearch.org/difference-between-alloc-init-and-new
Alguns selecionados são:
new
não suporta inicializadores personalizados (comoinitWithString
)alloc-init
é mais explícito quenew
A opinião geral parece ser que você deve usar o que quer que seja que seja confortável.
fonte
+newWithString:
também, se você já o implementou-initWithString
. Não é tão comum assim. Pessoalmente, eu sempre usonew
quando o inicializador designado éinit
tão curto e agradável.+newWithString:
. Isso quebra a separação de preocupações. Pois quando você só quer usar de-init
qualquer maneira, não há motivo para não usar+new
, no entanto.[[NSString alloc] initWithFormat:...]
e[NSString stringWithFormat:...]
são ambos equivalentes. Você está dizendo que a Apple violou a separação de preocupações e não deveria ter implementado dessa maneira? (Nota: Eu não estou tentando ser condescendente, eu gostaria apenas de obter mais informação e saber se seguindo o exemplo da Apple às vezes é uma má idéia.)Pergunta muito antiga, mas escrevi alguns exemplos apenas por diversão - talvez você ache útil;)
Na função principal, ambas as instruções:
e
resultam na mesma saída:
fonte
[[InitAllocNewTest alloc] init]
não será compilado enquanto[InitAllocNewTest new]
não for afetado. (Apologias para falta de quebras de linha, etc.)+new
é equivalente+alloc/-init
naNSObject
implementação da Apple . É altamente improvável que isso mude, mas dependendo do seu nível de paranóia, a documentação da Apple+new
parece permitir uma alteração na implementação (e quebre a equivalência) no futuro. Por esse motivo, como "explícito é melhor que implícito" e para continuidade histórica, a comunidade Objective-C geralmente evita+new
. No entanto, geralmente é possível identificar os recém-chegados Java ao Objective-C por seu uso obstinado+new
.fonte
+new
existe desde os dias da NeXT. Se alguma coisa+new
é um sinal de alguém que aprendeu objc há muito tempo; Vejo muitas pessoas que vêm de novo para o idioma, ou que o escrevem há anos, mas claramente após o boom do iOS, não têm idéia do que isso+new
significa. Segundo, como+new
é muito antiga e, desde os dias de NeXT, a Apple seria muito insana em modificá-lo de maneira a quebrar o código antigo, especialmente considerando que suas próprias bases de código provavelmente estão repletas dele.new
idioma vem do Smalltalk. Também é usado no Ruby, e o Objective-C e o Ruby derivam muitas sintaxes e convenções do Smalltalk.Freqüentemente, você precisará passar argumentos para
init
e, portanto, usará um método diferente, como[[SomeObject alloc] initWithString: @"Foo"]
. Se você está acostumado a escrever isso, tem o hábito de fazê-lo dessa maneira e, portanto,[[SomeObject alloc] init]
pode vir mais naturalmente disso[SomeObject new]
.fonte
Uma resposta curta é:
fonte
Para uma observação, eu pessoalmente uso
[Foo new]
se quero que algo no init seja feito sem usar seu valor de retorno em qualquer lugar. Se você não usar o retorno de[[Foo alloc] init]
qualquer lugar, receberá um aviso. Mais ou menos, eu uso[Foo new]
para colírio para os olhos.fonte
Estou muito atrasado para isso, mas quero mencionar que esse novo é realmente inseguro no Obj-C com o mundo Swift. O Swift criará apenas um método init padrão se você não criar nenhum outro inicializador. A chamada nova em uma classe rápida com um inicializador personalizado causará uma falha. Se você usar o assign / init, o compilador irá reclamar adequadamente que o init não existe.
fonte
Se new faz o trabalho para você, também tornará seu código modestamente menor. Caso contrário, você poderia chamar
[[SomeClass alloc] init]
muitos locais diferentes no seu código, criará um Hot Spot na implementação de new - ou seja, no tempo de execução objc - que reduzirá o número de falhas no cache.No meu entendimento, se você precisar usar um uso inicializador personalizado
[[SomeClass alloc] initCustom]
.Se não, use
[SomeClass new]
.fonte
init
função padrão e use-a.[[SomeClass alloc] init];
Se você precisar de parâmetros, ainda assim nunca faça algo assim, faça[[SomeClass alloc] initWith:...];
. Por fim, se você substituir ainit
função por uma implementação customizada, poderánew
criar um objeto e ele ainda chamará ainit
implementação customizada .