2014-02-20 5 views
1

Это прослушивало меня в течение долгого времени, и я пытался много раз искать его.Как я должен использовать переменные класса в Objective-C?

Когда я впервые начал изучать Objective-C, я помню, как я рассматривал переменные класса. Я видел много потоков при переполнении стека и в других местах, которые в основном говорили: «Objective-C не поддерживает переменные класса, такие как C, но есть некоторые обходные пути».

Чтение этого заставило меня уклониться от использования переменных класса, особенно потому, что я читал сотни раз, что глобальные переменные омрачают элегантность ООП.

Так что у меня очень открытый, упрямый и разговорный вопрос: Должен ли я использовать переменные класса в объекте C? Кроме того, я делаю это правильно?

Вот моя ситуация: я создаю приложение, и я создал класс обработки касаний, чтобы иметь дело со всеми входами, полученными от касаний экрана. Данные очень полезны, и я хотел бы, чтобы каждый спрайт имел доступ к нему.

Поскольку каждый объект является подклассом моего класса геймобжектов, я полагаю, что я просто сделать переменный класс, сделать так:

заголовка для класса геймобжекты:

+(SSTouchHandler *)touchHandler; 
+(void)setHandler:(SSTouchHandler *)handler; 

реализация для класса геймобжекты:

static SSTouchHandler *touchHandler = nil; 

+(SSTouchHandler *)touchHandler 
{ 
    if (touchHandler) 
     return touchHandler; 
    else 
     return nil; 
} 

+(void)setHandler:(SSTouchHandler *)handler 
{ 
    touchHandler = handler; 
} 

Теперь это работает. Это прекрасно работает.

Я могу обратиться к моему проводнику с помощью [GameObject touchHandler] из любого места, в котором я нуждаюсь.

Это все, что я мог когда-либо хотеть и многое другое.

Но должен ли я использовать этот метод? Я загрязняю красоту, которая является объектно-ориентированным программированием?

Есть ли способ, которым я должен подправить этот процесс, чтобы он работал оптимально?

Спасибо за вход и вход, я, вероятно, немного побеспокоил, я просто не хочу приступать к неправильной игровой структуре.

+1

Как и в других языках, статические переменные используются в Objective-C. Но их очень легко злоупотреблять, как и на других языках. Как правило, когда вы нажимаете «сладкое пятно» для разработки приложения, потребность в статистике падает до довольно низкого уровня. –

+0

Вот что я понял, имеет смысл. Это мое первое приложение (по крайней мере, первое, что я планирую завершить и выпуская), и я честно вижу только необходимость статической переменной ONE. Думаешь, я могу пойти на это? – IAmTheAg

+2

Блок 'if' в вашем методе' touchHandler' не нужен, просто выполните 'return touchHandler''. Если он равен нулю, он вернет нуль. – dreamlax

ответ

2

Я видел много потоков на переполнение стека и в других местах, которые в основном сказал, «Objective-C не поддерживает переменные класса, как C делает, но есть некоторые обходные пути.

» переменные класса «не имеет смысла в контексте C, поскольку C не является объектно-ориентированным.

Итак, у меня очень открытый, упрямый и разговорный вопрос: Должен ли я использовать переменные класса в объекте C? Кроме того, я делаю это правильно?

Это более общий вопрос ООП, чем что-либо конкретное для Objective-C. Ответ имеет тенденцию быть довольно субъективным, но в целом я бы сказал, чтобы избежать их, если вы не пытаетесь установить какое-либо свойство, которое влияет на все экземпляры класса.

Вот моя ситуация: Я делаю приложение, и настроить сенсорный класс обработки для решения всех материалов, полученных от экрана прикосновений. Данные довольно полезны, и я бы хотел, чтобы каждый спрайт имел доступ к нему.

Это звучит для меня как лучшего шаблона дизайна для этого было бы передать экземпляр SSTouchHandler в качестве параметра инициализатора объектов спрайтов, которые используют его. например:

@interface GameObject : NSObject 
- (id)initWithTouchHandler:(SSTouchHandler *)handler; 
@end 

Теперь, если вы действительно хотите использовать один и тот же экземпляр SSTouchHandler для каждого GameObject, у вас есть два варианта:

1) Контроллер/завод, который создает GameObject объекты должны создавать и поддерживать ссылку на один экземпляр SSTouchHandler, а затем инициализировать все новые экземпляры GameObject с ним. Например:

@interface GameObjectController : NSObject 
@property (nonatomic, strong, readonly) SSTouchHandler *touchHandler; 
- (GameObject *)newGameObject; 
@end 

@implementation 

- (id)init 
{ 
    if ((self = [super init])) { 
     _touchHandler = [[SSTouchHandler alloc] init]; 
    } 
    return self; 
} 

- (GameObject *)newGameObject 
{ 
    return [[GameObject alloc] initWithTouchHandler:self.touchHandler]; 
} 

@end 

2) Вы могли бы сделать SSTouchHandler в shared singleton и вызывать методы совместного экземпляра непосредственно от реализации GameObject. Тем не менее, общие одинарные версии не поощряются в ООП, поскольку они скрывают зависимости и затрудняют единичный тестовый код, который зависит от них. Вы не должны идти по этому маршруту, если не считаете это абсолютно необходимым.

реализации для класса геймобжекты: ...

Если вы решили, что модели выше, не подходят для вашего случая использования (и что иногда случается), да что, по существу, как бы реализовать свойства класса в Objective-C. Одна вещь:

if (touchHandler) 
     return touchHandler; 
    else 
     return nil; 

В этом нет необходимости, вы можете просто return touchHandler, так как он будет nil в любом случае, если не установлен.

+0

Спасибо, это очень подробный ответ. Я уверен, что мне понадобится TouchHandler для каждого экземпляра, и моим предыдущим решением было бросить тот же указатель на начальный TouchHandler (используя инициализацию). Общий синглтон похож на то, что мне нужно, и исследует его. Кроме того, первое решение - это то, с чем я побывал раньше (по тому, как он выглядит), и проблема заключалась в том, что во многих местах я создал GameObjects. Поэтому у меня возникли проблемы с их правильной инициализацией. – IAmTheAg

+0

Прочтите немного об общих синглонах, являющихся последним средством, поэтому я думаю, что буду придерживаться метода переменной класса. Он работает, и я это понимаю, и, насколько я могу судить, он работает довольно спокойно. Однако ваш ответ был очень полезным, и я также вижу, есть ли у решения № 1 потенциал. – IAmTheAg

+1

Для этой конкретной ситуации (основанной на моем понимании с учетом ограниченного контекста) кажется, что вам нужно использовать подход с переменной класса или ввести singleton _somewhere_ вниз, если вам нужно создать этот GameObject на вашем коде. Вы можете либо сделать «GameObjectController» синглтон, чтобы ваш другой код мог вызвать его, чтобы создать новые экземпляры GameObject, которые инициализируются совместно используемым обработчиком касаний, или сделать сам SSTouchHandler одиночным. На мой взгляд, лучшим решением будет общий синглтон 'GameObjectController' /' GameObjectFactory'. – indragie

2

Если это сработает, все готово. Я думаю, что есть некоторые улучшения. Во-первых, вы можете использовать экземпляр var здесь: он не сложнее, но он позволяет гибкость в будущем (например, если вы хотите сделать два представления бок о бок). Кроме того, использование голого указателя не так хорошо; класс здесь не владеет указателем, и его можно оставить болтливым! Определение touchHandler как свойства (также экземпляра var) позаботится об этой проблеме.

+0

Здесь вы можете помочь. Раньше я использовал переменную экземпляра для обработки этой функции. Я просто инициализирую все свои объекты с помощью указателя.Я даже настраивал его так, чтобы каждый раз, когда я добавлял ребенка в свою сцену (я упоминал, что я использую spritekit?), Он устанавливает мой дескриптор объекта. Проблема в том, что мне нужно постоянно находить способы установить эту переменную вверх, в зависимости от того, как инициализируются мои игровые объекты и откуда. Должен ли я просто сделать все мои игровые объекты захватчиком при инициализации? – IAmTheAg