Desde que comecei a trabalhar em aplicativos iOS e objetivo C, fico muito intrigado com os diferentes locais onde se pode declarar e definir variáveis. Por um lado temos a abordagem C tradicional, por outro temos as novas diretivas ObjectiveC que adicionam OO em cima disso. Vocês poderiam me ajudar a entender as melhores práticas e situações em que eu gostaria de usar esses locais para minhas variáveis e talvez corrigir meu entendimento atual?
Aqui está um exemplo de classe (.h e .m):
#import <Foundation/Foundation.h>
// 1) What do I declare here?
@interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
// 3) class-specific method / property declarations
@end
e
#import "SampleClass.h"
// 4) what goes here?
@interface SampleClass()
// 5) private interface, can define private methods and properties here
@end
@implementation SampleClass
{
// 6) define ivars
}
// 7) define methods and synthesize properties from both public and private
// interfaces
@end
- Meu entendimento de 1 e 4 é que essas são declarações e definições baseadas em arquivo de estilo C que não têm nenhuma compreensão do conceito de classe e, portanto, devem ser usadas exatamente como seriam usadas em C. Eu as vi usado para implementar singletons baseados em variáveis estáticas antes. Há outros usos convenientes que estou perdendo?
- Minha opinião sobre o trabalho com o iOS é que ivars quase foram completamente eliminados fora da diretiva @synthesize e, portanto, podem ser quase totalmente ignorados. É esse o caso?
- Com relação a 5: por que eu iria querer declarar métodos em interfaces privadas? Meus métodos de classe privada parecem compilar bem sem uma declaração na interface. É principalmente para facilitar a leitura?
Muito obrigado, pessoal!
fonte
Primeiro, leia a resposta de @BackmerB. É uma boa visão geral dos porquês e do que você deve fazer em geral. Com isso em mente, para suas perguntas específicas:
Nenhuma definição de variável real vai aqui (é tecnicamente legal fazer isso se você souber exatamente o que está fazendo, mas nunca faça isso). Você pode definir vários outros tipos de coisas:
Externs parecem declarações de variáveis, mas são apenas uma promessa de realmente declarar em outro lugar. Em ObjC, eles devem ser usados apenas para declarar constantes e, geralmente, apenas constantes de string. Por exemplo:
Em seguida, você
.m
declararia em seu arquivo a constante real:Conforme observado por DrummerB, isso é um legado. Não coloque nada aqui.
Sim.
Constantes externas, conforme descrito acima. Além disso, as variáveis estáticas do arquivo podem ser acessadas aqui. São equivalentes às variáveis de classe em outras linguagens.
Sim
Mas muito raramente. Quase sempre você deve permitir que o clang (Xcode) crie as variáveis para você. As exceções geralmente são em torno de ivars não ObjC (como objetos Core Foundation, e especialmente objetos C ++ se esta for uma classe ObjC ++), ou ivars que têm semânticas de armazenamento estranhas (como ivars que não combinam com uma propriedade por algum motivo).
Geralmente você não deve mais @synthesize. Clang (Xcode) fará isso por você, e você deve permitir.
Nos últimos anos, as coisas ficaram dramaticamente mais simples. O efeito colateral é que agora existem três eras diferentes (Fragile ABI, Non-fragile ABI, Non-fragile ABI + auto-syntheisze). Portanto, quando você vê o código mais antigo, pode ser um pouco confuso. Assim, confusão decorrente da simplicidade: D
fonte
Eu também sou muito novo, então espero não estragar nada.
1 e 4: Variáveis globais de estilo C: elas têm amplo escopo de arquivo. A diferença entre os dois é que, por serem extensos ao arquivo, o primeiro estará disponível para qualquer pessoa que importe o cabeçalho, enquanto o segundo não.
2: variáveis de instância. A maioria das variáveis de instância é sintetizada e recuperada / configurada por meio de acessadores usando propriedades porque torna o gerenciamento de memória simples e agradável, além de fornecer notação de ponto fácil de entender.
6: Os ivars de implementação são um tanto novos. É um bom lugar para colocar ivars privados, já que você deseja expor apenas o que é necessário no cabeçalho público, mas as subclasses não os herdam AFAIK.
3 e 7: Método público e declarações de propriedade, depois implementações.
5: Interface privada. Sempre uso interfaces privadas sempre que posso para manter as coisas limpas e criar uma espécie de efeito de caixa preta. Se eles não precisam saber sobre isso, coloque-o lá. Eu também faço isso para facilitar a leitura, não sei se há outros motivos.
fonte
Este é um exemplo de todos os tipos de variáveis declaradas em Objective-C. O nome da variável indica seu acesso.
Arquivo: Animal.h
Arquivo: Animal.m
Observe que as variáveis iNotVisible não são visíveis em nenhuma outra classe. Este é um problema de visibilidade, portanto, declará-los com
@property
ou@public
não altera isso.Dentro de um construtor, é uma boa prática acessar variáveis declaradas com o
@property
uso de sublinhado,self
para evitar efeitos colaterais.Vamos tentar acessar as variáveis.
Arquivo: Cow.h
Arquivo: Cow.m
Ainda podemos acessar as variáveis não visíveis usando o tempo de execução.
Arquivo: Cow.m (parte 2)
Vamos tentar acessar as variáveis não visíveis.
Arquivo: main.m
Isto imprime
Observe que consegui acessar o ivar de apoio,
_iNotVisible2
que é privado da subclasse. Em Objective-C todas as variáveis podem ser lidas ou definidas, mesmo aquelas que estão marcadas@private
, sem exceções.Não incluí objetos associados ou variáveis C porque são pássaros diferentes. Quanto às variáveis C, qualquer variável definida fora de
@interface X{}
ou@implementation X{}
é uma variável C com escopo de arquivo e armazenamento estático.Eu não discuti os atributos de gerenciamento de memória ou atributos somente leitura / leitura / gravação, getter / setter.
fonte