Objective C статические переменные класса - PullRequest
45 голосов
/ 17 мая 2011

Я новичок в Objective C и читаю книгу под названием "Visual Quickstart Guide: Objective-C". Автор Steven Holzner, Peachpit Press

В главе 6: Объектно-ориентированное программирование есть раздел под названием ИспользованиеПеременные класса, где он пишет:

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

И говорит, чтобы ввести следующий код:

#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

Книга неправильная или я что-то не так делаю?

Ответы [ 4 ]

97 голосов
/ 17 мая 2011

Вы объявляете статическую переменную в файле реализации (файл .m).Это должно работать:

// TheClass.h
@interface TheClass : NSObject
+ (int)count;
@end

// TheClass.m
static int theCount = 0;

@implementation TheClass
+ (int) count { return theCount; }
@end

Это не переменная класса как таковая;Objective-C не имеет понятия о переменной класса.Однако в сочетании с методом класса для извлечения этой переменной он функционирует аналогично переменной класса.Однако на самом деле это просто статическая переменная C, доступная для реализации класса.

15 голосов
/ 17 мая 2011

Я видел одно 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 . Это бесплатно, и это хорошее чтение.

10 голосов
/ 14 марта 2014

Если «переменная класса» требует больше, чем тривиальная инициализация, используйте 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;
}
6 голосов
/ 17 мая 2011

Вы должны объявить переменную в файле .m, где находится @implementation.Итак,

#import "TheClass.h"

static int count;

@implementation

...

@end

Важно отметить, что Objective-C фактически не поддерживает переменные класса.Но вы можете смоделировать их со статическими переменными, как мы делаем здесь.

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