Статическая строковая переменная в Objective C на iphone
Как создать и получить доступ к статической строке в iPhone (цель c)?
Я объявляю static NSString *str = @"OldValue"
в классе A.
Если я присвою это значение в классе B как str = @"NewValue"
.
Это значение сохраняется для всех методов класса B. Но если я получаю доступ к нему в классе C (после присвоения в B), я получаю его как OldValue.
Я что-то упускаю? Должен ли я использовать extern в других классах?
Спасибо и с уважением,
Yogini
Ответы
Ответ 1
Обновление: Как и в 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
Ответ 2
В отличие от Java, где статическая переменная используется для всех экземпляров класса, static
в C означает, что переменная доступна только из файла, в котором она объявлена. Он позволяет делать такие вещи, как объявлять статическую переменную внутри функции, которая устанавливает значение только в первый раз, как это.
Одна вещь, о которой вы не упоминали, - это отношения между классами A, B и C. Если они находятся в иерархии наследования, и вы ожидаете, что статическая переменная наследуется, как в Java, метод, описанный zpasternack будет работать.
Если три класса не связаны друг с другом, и вы просто хотите получить доступ к значению, объявленному в A, тогда extern
является более подходящим способом. В этом случае вы хотите объявить переменную как extern
в ClassA.h, а затем определить ее в Class.m. Пока ClassB и ClassC импортируют ClassA.h, они смогут ссылаться на одно и то же определение extern.
Одна тонкая точка заключается в том, что вместо использования extern
сама по себе она более надежна для использования OBJC_EXPORT
, которая определена в objc-api.h и обрабатывает компиляцию под С++. Вот пример кода:
// 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
vs. extern
. Однако, как принцип проектирования, инкапсуляция, обеспечиваемая путем переноса переменной с помощью методов класса, намного безопаснее, хотя и более сложна. В объектно-ориентированных языках, когда эффект, который вы пытаетесь достичь, относится к классу-статическому методу, инкапсуляция, вероятно, является правильным способом.