Статические переменные в Objective-C - что они делают?

Я видел несколько сообщений, обсуждающих, что такое статическая переменная, и я думаю, что получаю ее - но мне бы хотелось быстро написать (или найти) программу, которая использует как регулярную, так и статическую переменную, бок о бок, и посмотреть, как/когда они работают по-разному. Какой-то быстрый n грязный код, возможно, два int vars и несколько инструкций отслеживания NSLog, чтобы увидеть, КАК они разные.

У кого-нибудь есть подсказки/идеи/код, которые иллюстрируют, как статический var отличается от обычного?

Ответ 1

В C и Objective-C статическая переменная - это переменная, которая распределяется на все время жизни программы. Это контрастирует с автоматическими переменными, срок службы которых существует во время одного вызова функции; и динамически распределенные переменные, такие как объекты, которые могут быть освобождены из памяти, когда они больше не используются. Проще говоря, статическое значение переменной поддерживается во всех вызовах функций/методов. При объявлении вне функции статическая переменная видима для всего внутри файла, в котором она объявлена; при объявлении внутри функции или метода она видна только внутри этой функции или метода, но значение сохраняется между вызовами.

Скажите, что у вас есть это:

int f(void)
{
    int i = 5;
    i += 10;
    return i;
}

Каждый вызов f() возвращает значение 15.

Теперь скажите, что у вас есть это:

int g(void)
{
    static int i = 5;
    i += 10;
    return i;
}

При первом вызове g() возвращается значение 15. Во второй раз возвращается 25, так как i сохранил свое значение 15, а затем увеличил себя на 10. Третий вызов 35 будет возвращен. И так далее.

В контексте классов Objective-C статические переменные часто используются для имитации переменных класса, поскольку Objective-C не имеет переменных класса (другие языки, такие как Java, do). Например, скажем, вы хотите лениво инициализировать объект и возвращать только этот объект. Вы можете увидеть это:

static MyObject *obj = nil;

@implementation MyObject

+ (id)sharedObject
{
    if (obj == nil) obj = [[MyObject alloc] init];
    return obj;
}

@end

obj будет инициализирован при первом вызове classObject; последующие вызовы classObject возвращают тот же объект. Вы можете проверить это, зарегистрировав адрес объекта:

NSLog(@"obj is at %p", [MyObject sharedObject]);
NSLog(@"obj is at %p", [MyObject sharedObject]);    // Will print the same address both times

Кроме того, obj будет виден всем методам в MyObject.

Этот метод используется для реализации одноэлементных классов в Objective-C.

Ответ 2

static работает в основном как в C.

  • Он может либо инициализировать переменную только один раз.

  • Объявление переменной static в файле выше блока @implementation будет доступно только для всего файла.

Ответ 3

"static" больше относится к атрибутам переменной (кто, где), а не только к значению. В отличие от других языков, где он относится исключительно к значению.

  • Sticky

Это похоже на привязку var к определенному месту, будь то внутри функции или в реализации.

  • Частный

Он имеет аналогичные атрибуты для "private" var, в которых он не отображается для родного брата или родителей, но дети могут получить доступ.

  • Классный

Это объявление со значением по умолчанию. Как и на других языках, где вы определяете vars внутри класса и присваиваете свое значение по умолчанию:

private int myNumber = 3;

Это дает нам "классные" переменные внутри функций. Объявите их один раз, затем, когда функция управляет значением, значение сохраняется. В следующий раз, когда вызывается функция, значение будет таким же, как и после предыдущего "цикла", так же, как вы ожидали, что значение переменной класса останется после манипуляции.