Compartilhamento de tecnologia

isa em Objective-C não é mais um simples ponteiro de estrutura

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Aprenda sobre o Objective-C isa estrutura de memória do ponteiro

Em Objective-C,isa Os ponteiros são uma ponte importante entre objetos e classes. Ele não apenas ajuda o sistema de tempo de execução a identificar o tipo de objeto, mas também participa de algumas otimizações de memória e desempenho.Este artigo explicará em profundidadeisa A estrutura de memória dos ponteiros, incluindo sua evolução nas implementações antigas e modernas.

o que é isa ponteiro?

Todo objeto Objective-C tem um isa Um ponteiro que aponta para o objeto de classe de um objeto.O próprio objeto de classe também é um objeto, e seuisa O ponteiro aponta para um objeto de metaclasse.Objetos metaclasse armazenam métodos de classe e seusisa O ponteiro aponta para a metaclasse raiz (geralmenteNSObject metaclasse).

Cedo isa estrutura de ponteiro

Nas primeiras implementações do Objective-C,isa O ponteiro simplesmente aponta para uma estrutura de objetos de classe. Aqui está um exemplo típico de implementação inicial:

struct objc_object {
    Class isa; // 指向类对象的指针
};

typedef struct objc_class *Class; // Class 的本质是 objc_class 类型的结构体指针
struct objc_class {
    Class isa; // 指向元类对象的指针
    Class super_class; // 指向父类对象的指针
    // 其他类相关的元数据
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Sob esta estrutura:

  • Objeto isa O ponteiro aponta para o objeto de classe.
  • semelhante a um objeto isa Ponteiro aponta para objeto de metaclasse.
  • objeto de metaclasse isa O ponteiro aponta para o objeto de metaclasse raiz.

moderno isa estrutura de ponteiro

Em sistemas de 64 bits e tempos de execução modernos do Objective-C,isa Os ponteiros foram redesenhados como uma união mais complexa (union isa_t ), que contém não apenas ponteiros para objetos de classe, mas também outros sinalizadores e informações para otimizar o uso e o desempenho da memória.A seguirisa_t Um exemplo simplificado de estrutura:

union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    Class cls; // 指向类对象的指针
    uintptr_t bits; // 包含位域信息的位模式

    struct {
        uintptr_t nonpointer        : 1;  // 是否启用优化的 non-pointer isa
        uintptr_t has_assoc         : 1;  // 是否有关联对象
        uintptr_t has_cxx_dtor      : 1;  // 是否有 C++ 析构函数
        uintptr_t shiftcls          : 33; // 类指针(经过位移和压缩)
        uintptr_t magic             : 6;  // 调试用的魔数
        uintptr_t weakly_referenced : 1;  // 是否被弱引用
        uintptr_t deallocating      : 1;  // 是否正在释放
        uintptr_t has_sidetable_rc  : 1;  // 是否有辅助引用计数表
        uintptr_t extra_rc          : 19; // 额外的引用计数
    };
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Explicação do campo de estrutura

  • não apontador:instruir isa Seja do tipo não ponteiro (otimiza o layout da memória, armazena informações adicionais).
  • tem_associação: Se o objeto possui referências associadas (Referências Associativas).
  • tem_cxx_dtor: se o objeto tem um destruidor C++ e se o destruidor precisa ser chamado.
  • shiftcls: Ponteiro de classe, que armazena as informações de classe do objeto (após deslocamento e compactação).
  • Magia: Número mágico usado para depuração e verificação de tempo de execução.
  • fracamente_referenciado: Se o objeto é apontado por uma referência fraca.
  • desalocando: Se o objeto está sendo liberado.
  • tem_tabela_lateral_rc: Se a contagem de referência do objeto está armazenada na tabela auxiliar (Side Table).
  • extra_rc: Contagem de referência adicional para otimizar o uso de memória.

Armazenamento e gerenciamento de contagens de referência

Nas primeiras implementações do Objective-C, a contagem de referências geralmente era armazenada diretamente no objeto como parte da estrutura do objeto. Por exemplo:

struct objc_object {
    Class isa; // 指向类对象的指针
    uintptr_t retainCount; // 引用计数
};
  • 1
  • 2
  • 3
  • 4

Nos tempos de execução modernos do Objective-C, a contagem de referência ocorre via isa A estrutura otimizada de ponteiros e a estrutura de dados auxiliar da Side Table são gerenciadas.

  • Contagem de referência em linha: As informações de contagem de referência parcial são armazenadas em isa Em estruturas otimizadas de ponteiros, por ex.extra_rc campo.
  • Mesa de apoio: quando a contagem de referência excede isa Quando o intervalo que um ponteiro pode representar, a contagem de referência é armazenada em uma estrutura de dados auxiliar chamada Side Table.

Moderno isa Vantagens dos ponteiros

  • Otimização de memória: Ao armazenar mais informações (como contagens de referência, sinalizadores) em isa Nos ponteiros, o acesso a outras áreas da memória é reduzido e o desempenho é melhorado.
  • Melhorias de desempenho: operações de leitura de memória reduzidas porque mais informações podem ser obtidas em uma leitura de memória.
  • Metadados mais ricos: pode conter mais informações de tempo de execução, ajudando a melhorar a flexibilidade e a eficiência do tempo de execução.

Exemplo de uso

Embora os desenvolvedores muitas vezes não interajam diretamente com isa Os ponteiros interagem, mas compreender sua estrutura é útil para depurar e otimizar o desempenho. Aqui está um exemplo de uso que exibe o tipo de um objeto acessando suas informações de classe:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface MyClass : NSObject
@end

@implementation MyClass
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MyClass *obj = [[MyClass alloc] init];
        Class cls = object_getClass(obj);
        NSLog(@"Class name: %s", class_getName(cls));
        
        // 访问 isa 指针信息(需要通过运行时函数)
        NSLog(@"isa pointer: %p", *(uintptr_t *)obj);
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

Resumir

isa Os ponteiros desempenham um papel importante no tempo de execução do Objective-C, desde os primeiros simples apontamentos para objetos de classe até os modernos e complexosisa_t estrutura, o que ajuda a otimizar o uso e o desempenho da memória.entenderisa A evolução de ponteiros e estruturas de memória pode nos ajudar a compreender melhor o mecanismo de tempo de execução do Objective-C e a escrever código eficiente.

Espero que este artigo possa ajudá-lo a obter uma compreensão mais profunda do Objective-C isa Estrutura de memória do ponteiro. Se você tiver alguma dúvida ou sugestão, deixe uma mensagem para discussão.