Как переместить нестатические переменные из интерфейса в реализацию в ObjectiveC?

Я пытаюсь написать статическую библиотеку касания какао. Для простоты я бы предпочел не использовать частные переменные в моем файле интерфейса. Код прямо сейчас выглядит так:

файл интерфейса (myView.h):

@interface myView: UIView {

NSTimer * myTimer;

}

@end

файл реализации (myView.h)

@implementation myView

@end

Этот указатель NSTimer — просто частная переменная, поэтому я попробовал следующее: (не работает)

файл интерфейса (myView.h):

@interface myView: UIView {

}

@end

файл реализации (myView.h)

NSTimer * myTimer;

@implementation myView

@end

Вроде работает, однако оказалось, что таймер теперь статическая переменная.

Я делаю что-то неправильно или нет решения?


person jantimon    schedule 24.09.2009    source источник


Ответы (3)


Вы не можете определить переменные экземпляра в файле реализации.

Возможное решение состоит в том, чтобы иметь приватную структуру, содержащую приватные переменные, и иметь одну публично объявленную приватную переменную, указывающую на эту приватную структуру:

@interface MyView {
   void *privateData;
}

Файл реализации:

typedef struct {
   NSTimer *myTimer;
}  PrivateData;


@implementation MyView()

@property (readonly) PrivateData *privateData;

@end


@implementation MyView

- (id) init {
   if (self = [super init]) {
       privateData = malloc(sizeof(PrivateData));

       self.privateData->myTimer = nil; // or something else
   } 

   return self;
}

-(PrivateData *) privateData {
    return (PrivateData *) self->privateData;
}

- (void) myMethod {
   NSTimer *timer = self.privateData->myTimer;
}

- (void) dealloc {
    // release stuff inside PrivateData
    free(privateData);
    [super dealloc];
}

@end

Это не красиво, но это работает. Может быть, есть лучшие решения.

person Philippe Leybaert    schedule 24.09.2009
comment
это действительно некрасиво (+1) в любом случае - person jantimon; 24.09.2009
comment
Это должно быть обновлено. Теперь вы можете иметь переменные экземпляра, определенные в вашем файле реализации (.m). - person mahboudz; 16.05.2012
comment
Обновленное решение: @implementation ClassName { // Instance variable declarations. } stackoverflow.com/questions/10407848/ - person smileham; 04.06.2016

Просто примечание; пытаться скрыть iVar ради безопасности глупо. Не беспокойтесь.

Однако для простоты это имеет значение.

Тем не менее, пара решений:

(1) Если вы нацелены на iPhone OS или 64-битную версию Cocoa, вы можете @synthesize ivar:

Фу.ч:

@interface Foo:NSObject
@property(readwrite, copy) NSString *publiclyReadwriteNoiVar;
@property(readonly, copy) NSString *publiclyReadonlyPrivatelyReadwriteNoiVar;
@end

Фу.м:

@interface Foo()
@property(readwrite, copy) NSString *privateProperty;
@end

@implementation Foo
@synthesize publiclyReadwriteNoiVar, publiclyReadonlyPrivatelyReadwriteNoiVar, privateProperty;
@end

(2) Используйте частный подкласс, похожий на кластеры классов:

Фу.ч:

@interface Foo:NSObject
@end

Фу.м:

@interface RealFoo:Foo
{
    .... ivars here ....
}
@end
@implementation RealFoo
@end

@implementation Foo
+ (Foo *) convenienceMethodThatCreatesFoo
{
   .... realFoo = [[RealFoo alloc] init]; ....
   return realFoo;
}
@end
person bbum    schedule 24.09.2009

В зависимости от цели вашей инкапсуляции также существует директива @private:

модификаторы доступа

person pzearfoss    schedule 24.09.2009