Perché il puntatore isa non è cablato nelle classi Objective-C?

1

Ho studiato il runtime Objective-C per alcuni anni, e ho persino hackerato un po 'di libobjc (sia di Apple che di GNUStep), e mi sono chiesto una decisione di progettazione sui compilatori.

Ci si aspetta che ogni oggetto Objective-C abbia le sue dimensioni almeno di sizeof(Class) , con il suo primo campo che è Class isa , come sembra in struct objc_object . Vediamo che è dichiarato esplicitamente nelle classi radice come NSObject e vecchio defunct Object . Sappiamo anche che il runtime aggiunge il puntatore ai nuovi oggetti quando vengono creati da class_createInstance() (vedi esempio di codice sotto).

Quindi la mia domanda è: allora perché il puntatore isa non è automaticamente anteposto alle dichiarazioni di classe? Perché ha bisogno che lo dichiarino esplicitamente anche se questo è soggetto a errori?

Esempio con codice errato:

#import <stdlib.h>
#import <stdio.h>
#import <objc/runtime.h>

@interface Foo {
  @public
  int x;
};
- (void)bar;
@end

@implementation Foo
- (void)bar {
  printf("bar\n");
};
@end

int main() {

  Class cls = objc_getClass("Foo");
  printf("cls = %p\n", cls);

  // Returns sizeof(int)
  printf("cls size = %ld\n", class_getInstanceSize(cls));

  Foo *obj = class_createInstance(cls, 0);
  printf("obj = %p\n", obj);

  // Are we saving isa?
  printf("hmm: %d\n", *((Class *)obj) == cls);

  // We are! This works ;)
  [obj bar];

  // Evil code
  obj->x = 10;

  // Did we do something wrong?
  printf("hmm: %d\n", *((Class *)obj) == cls);

  // Yeah, we did! Segfault here!
  [obj aaa];

  return EXIT_SUCCESS;
};
    
posta paulotorrens 04.07.2015 - 04:41
fonte

1 risposta

1

È un dettaglio di implementazione del runtime Objective-C Apple / GNUstep / OpenStep. libobjc è il runtime Objective-C di Apple e le classi Cocoa / GNUstep come NSObject sono legate al runtime Objective-C.

Objective-C (in origine) aggiunge semplicemente un livello minimo di sintassi su C, e non c'è ragione, dal puro punto di vista del linguaggio Objective-C, che gli oggetti debbano essere disposti in un modo particolare.

Potresti teoricamente scrivere il tuo runtime Objective-C che disegna oggetti e altre cose in modo diverso, e poi scrivi il tuo framework Objective-C, con le tue classi root per lavorare con quel runtime.

    
risposta data 06.07.2015 - 01:04
fonte

Leggi altre domande sui tag