Статические переменные класса Objective C
Я новичок в Objective C и читаю книгу под названием "Visual Quickstart Guide: Objective-C" Стивена Хольцнера, Press Peachpit Press
В главе 6: Объектно-ориентированное программирование имеется раздел "Использование переменных класса", где он пишет:
Вы можете создавать переменные класса для использования с ваши классы, но theres заминка: каждый объект этого класса имеет одну и ту же переменную, поэтому если один объект изменяет переменную класса, то переменная изменяется для всех объектов. Вы создаете переменные класса со статическим ключевым словом. Переменные класса часто полезны: например, вы можете использовать переменную класса, чтобы отслеживать количество созданных объектов определенного класса в программе. Вы сделаете это в этой задаче.
И говорит ввести следующий код:
#import <stdio.h>
#import <Foundation/NSObject.h>
@interface TheClass: NSObject
static int count; //error: cannot declare variable inside @interface or @protocol
+(int) getCount;
@end
...
Этот код дает мне ошибку в Xcode 4:
Невозможно объявить переменную внутри @interface или @protocol
Является ли книга неправильной или я делаю что-то неправильно?
Ответы
Ответ 1
Вы объявляете статическую переменную в файле реализации (.m
файл). Это должно работать:
// TheClass.h
@interface TheClass : NSObject
+ (int)count;
@end
// TheClass.m
static int theCount = 0;
@implementation TheClass
+ (int) count { return theCount; }
@end
Это не переменная класса per se; Objective-C не имеет понятия переменной класса. Однако в сочетании с методом класса для извлечения этой переменной он работает аналогично переменной класса. Тем не менее, это действительно просто статическая переменная C, доступная для реализации класса.
Ответ 2
Я видел один Visual Quickstart Guide о Unix, и он сосал большое время. Кажется, что это не намного лучше, по крайней мере, из образца. Правильный способ создания переменной класса в Objective-C выглядит следующим образом:
// Counted.h
@interface Counted : NSObject
+ (NSUInteger) numberOfInstances;
@end
// Counted.m
#import "Counted.h"
static NSUInteger instances = 0;
@implementation Counted
- (id) init {
…
instances++;
…
}
- (void) dealloc {
instances--;
}
+ (NSUInteger) numberOfInstances {
return instances;
}
@end
Это фактически статическая переменная, а не настоящая переменная класса. Но вы не должны слишком беспокоиться о переменных класса, они обычно являются признаком того, что вы делаете что-то неправильно. (Я немного упрощаю, но не много.)
Если вы ищете достойную книгу Objective-C, прочитайте одну из них Apple. Его свободное и хорошее чтение.
Ответ 3
Если для переменной класса требуется более тривиальная инициализация, используйте dispatch_once
:
@interface Foo ()
+ (Foo *)singleton;
@end
+ (Foo *)singleton {
static Foo *_singleton;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_singleton = [[Foo alloc] init];
});
return _singleton;
}
Ответ 4
Вы должны объявить переменную в файле .m, где ставится @implementation. Таким образом,
#import "TheClass.h"
static int count;
@implementation
...
@end
Важно отметить, что Objective-C фактически не поддерживает переменные класса. Но вы можете имитировать их со статическими переменными, как мы это делаем.