Подтвердить что ты не робот

Невозможно объявить переменную внутри @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 если это реальная ошибка с моей стороны? И почему код все еще был скомпилирован и может быть запущен без каких-либо проблем?

4b9b3361

Ответ 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, обычно после включений и вне деклараций интерфейса.

Также неплохо было бы инициализировать глобальные указатели объектов на нуль, иначе они могут содержать ссылку на объект мусора.