6 Stimmen

Verstecke Instanzvariable aus der Kopfzeile in Objective C

Ich bin auf eine Bibliothek gestoßen, die in Objective C geschrieben ist (ich habe nur die Header-Datei und die .a-Binärdatei). In der Header-Datei sieht es so aus:

@interface MyClass : MySuperClass 
{ 
    //hier steht nichts
}

@property (nonatomic, retain) MyObject anObject;
- (void)someMethod;

Wie kann ich dasselbe erreichen? Wenn ich versuche, eine Eigenschaft ohne die entsprechende Instanzvariable innerhalb der {} des Interfaces zu deklarieren, wird mir der Compiler einen Fehler melden. Letztendlich möchte ich die interne Struktur meiner Klasse in der .a verbergen und nur die notwendigen Methoden in der Headerdatei freigeben. Wie deklariere ich Instanzvariablen in der .m? Kategorien erlauben es mir nicht, Instanzvariablen hinzuzufügen, nur Methoden.

1voto

Chuck Punkte 228137

Zwei Möglichkeiten:

  1. Es könnte sein, dass die moderne Laufzeitumgebung die Fähigkeit hat, Instanzvariablen zu synthetisieren, wie bbum vorgeschlagen hat.
  2. Die Eigenschaft könnte in dieser Klasse keine zugrunde liegende Instanzvariable haben. Eigenschaften haben nicht unbedingt eine Eins-zu-Eins-Zuordnung mit Instanzvariablen.

0voto

epatel Punkte 45365

Wie wäre es mit einem Makro-Trick?

Code unten getestet

  • mit Dylibs getestet - hat gut funktioniert
  • Mit Subclassing getestet - Warnung! wird brechen, ich stimme zu, dass dies den Trick nicht so nützlich macht, aber ich denke trotzdem, dass es etwas darüber aussagt, wie ObjC funktioniert...

MyClass.h

@interface MyClass : NSObject {
#ifdef MYCLASS_CONTENT
    MYCLASS_CONTENT // Hier wird nichts preisgegeben
#endif
}
@property (nonatomic, retain) NSString *name;
@property (nonatomic, assign) int extra;
- (id)initWithString:(NSString*)str;
@end

MyClass.m

// Definiere den erforderlichen Klasseninhalt hier vor dem #import "MyClass.h"
#define MYCLASS_CONTENT \
  NSString *_name; \
  int _extra; \
  int _hiddenThing; 

#import "MyClass.h"

@implementation MyClass
@synthesize name=_name;
@synthesize extra=_extra;

- (id)initWithString:(NSString*)str
{
    self = [super init];
    if (self) {
        self.name = str;
        self.extra = 17;
        _hiddenThing = 19;
    }
    return self;
}

- (void)dealloc
{
    [_name release];
    [super dealloc];
}

@end

0voto

Jared Pochtar Punkte 4817

MACHEN Sie das nicht, aber ich denke, es sollte erwähnt werden, dass die Laufzeit die Möglichkeit hat, Instanzvariablen hinzuzufügen wann immer Sie möchten mit class_addIvar.

0voto

Aaron Punkte 11987

Ich konnte folgendes in meiner Bibliothek tun:

myLib.h:

@interface MyClass : SomeSuperClass  {
  // Nichts hier drin
}

- (void)someMethods;
@end

myLib.m

@interface MyClass () 
    SomeClass *someVars;

    @property (nonatomic, retain) SomeClass *someVars;
@end

@implementation MyClass

@synthesize someVar;

- (void)someMethods {
}
@end

Das Protokoll ist optional. Ich glaube, dass dadurch auch alle Instanzvariablen privat werden, obwohl ich mir nicht zu 100% sicher bin. Für mich ist es nur eine Schnittstelle zu meiner statischen Bibliothek, also ist es nicht wirklich wichtig.

Wie auch immer, ich hoffe, das hilft dir weiter. An alle anderen, die das lesen, lasst es mich wissen, wenn dies generell schlecht ist oder unvorhergesehene Konsequenzen hat. Ich bin selbst ziemlich neu in Obj-C, also könnte ich immer Ratschläge von Erfahrenen gebrauchen.

-1voto

tofudev Punkte 1

Ich denke nicht, dass der folgende Code, der in einer anderen Antwort geschrieben wurde, wie erwartet funktioniert. Das in der Erweiterungsklasse definierte "SomeClass *someVars" ist kein Instanzvariablen von MyClass. Ich denke, es handelt sich um eine C-Globale Variable. Wenn Sie someVars synthesieren, erhalten Sie einen Kompilierungsfehler. Und self.someVars funktioniert auch nicht.

myLib.h

@interface MyClass : SomeSuperClass  {
    // Nichts hier
}

- (void)someMethods;
@end

myLib.m

@interface MyClass ()
    SomeClass *someVars;

    @property (nonatomic, retain) SomeClass *someVars;
@end

@implementation MyClass

@synthesize someVar;

- (void)someMethods {
}
@end

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X