Jaki jest podstawowy mechanizm syntezy ivar we współczesnym runtime Objective C

Jedną z cech współczesnego (64-bitowego systemu operacyjnego OS X i iPhone OS) runtime Objective C jest możliwość dynamicznego syntetyzowania ivarów przez właściwości bez wyraźnego deklarowania ich w klasie:

@interface MyClass : NSObject {
//  NSString *name; unnecessary on modern runtimes
}

@property (retain) NSStrng *name;

@end

@implementation MyClass

@synthesize name;

@end

W sporej części mojego kodu używam niestandardowych implementacji gettera w celu zainicjalizowania właściwości:

- (NSString *) name {
  if (!name) {
    name = @"Louis";
  }

  return name;
}

Powyższe jest niezgodne z zsyntetyzowanymi ivarami, ponieważ musi uzyskać dostęp do Ivara, który nie jest zadeklarowany w nagłówku. Z różnych powodów chciałbym update a number of my personal framework to use synthesized ivars when built on the modern runtimes, the above code needs to be modified to work with synthesized ivars in to achieve that cel.

Podczas gdy dokumentacja Objective C 2.0 stwierdza, że zsyntetyzowane Accesory w nowoczesnym środowisku uruchomieniowym będą syntetyzować ivar przy pierwszym użyciu. Nie określa, jaki mechanizm niskiego poziomu jest używany do tego celu. Czy to robi class_getInstanceVariable (), są ograniczenia na class_addIvar() czy jest to nieudokumentowana funkcja int on objective C 2.0 runtime? Chociaż mógłbym zaimplementować własną pamięć boczną dla danych wspierających moje właściwości, wolałbym raczej użyć mechanizmu, którego używają syntetyzowane Accesory.

Author: Ned Batchelder, 2008-11-08

3 answers

Przejrzałam jeszcze raz dokumentację i myślę, że źle ją odczytujesz. Zsyntetyzowane Ivary są tworzone w czasie kompilacji, a nie w czasie wykonywania.

Zgodnie z dokumentacją Objective-C 2.0 :

Istnieją różnice w zachowaniu, które zależą od runtime (patrz także "różnice Runtime"):

Dla starszych środowisk uruchomieniowych zmienne instancji muszą być już zadeklarowane w bloku @interface. Jeśli zmienna instancji o tej samej nazwie i typ zgodny, ponieważ właściwość istnieje, jest używana-w przeciwnym razie pojawi się błąd kompilatora.

W nowoczesnych przestrzeniach uruchamiania zmienne instancji są syntetyzowane w razie potrzeby. Jeśli zmienna instancyjna o tej samej nazwie już istnieje, jest używana.

Więc wszystko co musisz zrobić to zadeklarować zmienną instancji, której potrzebujesz, a ten sam kod będzie działał w obu środowiskach...

 21
Author: Mark Bessey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-08 20:30:58

To czego szukasz to @ nazwa syntetyzowana, np.:

@synthesize name = _name;

...

- (NSString *) name {
    if (!name) {
        _name = @"Louis";
    }

    return _name;
}
 0
Author: Farcaller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-28 13:51:50

Dodajesz właściwości w czasie wykonywania za pomocą Protokołu NSKeyValueCoding .

[myObject setValue:@"whatever" forKey:@"foo"];
 -6
Author: jazzdev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-04 18:49:44