Невозможно объявить переменную внутри @interface или @protocol - PullRequest
20 голосов
/ 31 октября 2011

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

Ответы [ 4 ]

30 голосов
/ 01 ноября 2011

Они не могут туда пойти. Вы можете поместить их в фигурные скобки {} так:

@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
12 голосов
/ 31 октября 2011

Вы пытаетесь определить их как общедоступных членов в классе? Классы в 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 голосов
/ 31 октября 2011

Компилятор жалуется на переменные, находящиеся в блоке @interface, поэтому уберите их из него, либо выше @interface, либо ниже @end.Возможно, вы захотите изменить их на extern s в заголовке и объявить их в файле .m.

1 голос
/ 31 октября 2011

C Глобальные переменные должны быть объявлены в файлах реализации .m, а не в заголовочных файлах .h.Объявление extern может идти в заголовочных файлах .h, обычно после включений и за пределами объявлений интерфейса.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...