Статическая строковая переменная в Objective C на iPhone - PullRequest
26 голосов
/ 11 июня 2009

Как создать и получить доступ к статической строке в iPhone (цель c)? Я объявляю static NSString *str = @"OldValue" в классе А.

Если я назначу это значение в классе B как str = @"NewValue". Это значение сохраняется для всех методов в классе B. Но если я получаю доступ к нему в классе C (после присваивания в B), я получаю его как OldValue. Я что-то пропустил? Должен ли я использовать extern в других классах?

Спасибо и С уважением, Yogini

Ответы [ 2 ]

44 голосов
/ 11 июня 2009

Обновление: Начиная с Xcode 8, Objective-C имеет свойства класса. Обратите внимание, это в основном синтаксический сахар; эти свойства не синтезируются автоматически, поэтому реализация в основном не изменилась.

// MyClass.h
@interface MyClass : NSObject
@property( class, copy ) NSString* str;
@end

// MyClass.m
#import "MyClass.h"

@implementation MyClass

static NSString* str;

+ (NSString*) str 
{
    return str;
}

+ (void) setStr:(NSString*)newStr 
{
    if( str != newStr ) {
        str = [newStr copy];
    }
}
@end


// Client code
MyClass.str = @"Some String";
NSLog( @"%@", MyClass.str ); // "Some String"

См. WWDC 2016 Что нового в LLVM . Часть свойства класса начинается примерно через 5 минут.

Оригинальный ответ:

Objective-C не имеет переменных класса, что, я думаю, вы ищете. Вы можете подделать это со статическими переменными, как вы делаете.

Я бы рекомендовал поместить статическую строку NSString в файл реализации вашего класса и предоставить методы класса для доступа к нему / его изменения. Примерно так:

// MyClass.h
@interface MyClass : NSObject {
}
+ (NSString*)str;
+ (void)setStr:(NSString*)newStr;
@end

// MyClass.m
#import "MyClass.h"

static NSString* str;

@implementation MyClass

+ (NSString*)str {
    return str;
}

+ (void)setStr:(NSString*)newStr {
    if (str != newStr) {
        [str release];
        str = [newStr copy];
    }
}
@end
30 голосов
/ 11 июня 2009

В отличие от Java, где статическая переменная ограничена для всех экземпляров класса, static в C означает, что переменная доступна только из файла, в котором она объявлена. Это позволяет вам делать такие вещи, как объявление статической переменной внутри функции, которая устанавливает значение только в первый раз, вот так .

Одна вещь, которую вы не упомянули, это отношения между классами A, B и C. Если они находятся в иерархии наследования, и вы ожидаете, что статическая переменная будет наследоваться, как в Java, метод, описанный zpasternack будет работать.

Если три класса не связаны, и вы просто хотите получить доступ к значению, объявленному в A, тогда extern является более подходящим способом. В этом случае вы хотите объявить переменную как extern в ClassA.h, а затем определить ее в Class.m. Пока ClassB и ClassC импортируют ClassA.h, они смогут ссылаться на одно и то же внешнее определение.

Одна тонкость в том, что вместо использования extern более надежно использовать OBJC_EXPORT, который определен в objc-api.h и также обрабатывает компиляцию в C ++. Вот пример кода:

// ClassA.h
OBJC_EXPORT NSString* commonString;
...

// ClassA.m
NSString* commonString = @"OldValue";

// ClassB.m
#import "ClassA.h"
...
commonString = @"NewValue"; // Can be inside a function or method

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

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