Невозможно объявить переменную внутри @interface или @protocol
У меня есть приложение iOS, созданное с самого начала с ошибкой в нем. Поскольку источник был создан из шаблона, его appdelegate.h выглядит так:
@interface myAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
myViewController *viewController;
}
BOOL myBool; // intended to be globally accessible
NSString *myString; // intended to be globally accessible
@end
Я ссылаюсь на myBool и * myString из многих других исходных файлов .m относительно глобальных переменных.
Ниже XCode 3.2.6, я не могу вспомнить, какие проблемы возникают во время компиляции.
В 3.2.6 при компиляции появилось предупреждение, указывающее на эти "глобальные" переменные в appdelegate.h, говоря: "Невозможно объявить переменную внутри @interface или @protocol". Поскольку никаких дополнительных проблем с компиляцией или во время работы приложения не возникало, к сожалению, я не рассматривал эти предупреждения.
Теперь, используя XCode 4.2, я не могу скомпилировать этот источник, потому что первые предупреждения превратились в ошибки сборки. Они ссылаются и указывают на каждую из этих строк в разных файлах .m, где есть ссылка на "глобальные переменные".
Есть ли простой способ исправить эту проблему, учитывая, что я все еще хочу получить доступ к этим переменным/ссылкам как глобальным?
Дополнительный вопрос: пока я оцениваю полученные ответы (спасибо за вас), еще один вопрос: любая идея, почему предупреждение не было указано ниже XCode v3.2.6, и только предупреждения в 3.2.6 если это реальная ошибка с моей стороны? И почему код все еще был скомпилирован и может быть запущен без каких-либо проблем?
Ответы
Ответ 1
Они не могут туда попасть. Вы можете поместить их в фигурные скобки {} следующим образом:
@interface myAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
myViewController *viewController;
BOOL myBool; // intended to be globally accessible
NSString *myString; // intended to be globally accessible
}
@end
И это делает их глобальными для класса реализации. Но если вы хотите, чтобы они были глобальными для каждого класса в вашем приложении, вы должны поместить их в файл App-Prefix.pch:
//
// Prefix header for all source files of the ... project
//
#import <Availability.h>
BOOL myBool; // intended to be globally accessible
NSString *myString; // intended to be globally accessible
#ifndef __IPHONE_3_0
Ответ 2
Вы пытаетесь определить их как публичных членов класса? Классы в Objective-C отличаются от других языков, с которыми вы, возможно, знакомы. За пределами фигурных скобок вы можете определять только методы. Если вы хотите сделать общедоступный элемент, определите их как свойства:
@interface myAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
myViewController *viewController;
BOOL _myBool;
NSString *_myString;
}
@property BOOL myBool; // intended to be globally accessible
@property NSString *myString; // intended to be globally accessible
@end
Затем в вашей @implementation сделайте что-то вроде:
@implementation myAppDelegate
@synthesize myBool = _myBool;
@synthesize myString = _myString;
Затем вы можете получить к ним доступ как myObject.myBool
и т.д.
Если вы просто пытаетесь сделать их статическими ( "глобальными" ) данными для всех экземпляров класса, то, как говорили другие плакаты, вы хотите переместить определение в свой .m
файл (и в идеале объявить их static
, поэтому они не будут вызывать проблемы со ссылками).
Ответ 3
Компилятор жалуется на переменные, находящиеся в блоке @interface
, поэтому выведите их из него выше или ниже @interface
или ниже @end
. Вероятно, вы, вероятно, захотите изменить их на extern
в заголовке и фактически объявить их в файле .m.
Ответ 4
C Глобальные переменные должны быть объявлены в файлах реализации .m, а не в файлах заголовка .h. Объявление extern может входить в заголовочные файлы .h, обычно после включений и вне деклараций интерфейса.
Также неплохо было бы инициализировать глобальные указатели объектов на нуль, иначе они могут содержать ссылку на объект мусора.