如何在 Objective-C 中声明类级属性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/695980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:19:14  来源:igfitidea点击:

How do I declare class-level properties in Objective-C?

objective-ccocoaoop

提问by mamcx

Maybe this is obvious, but I don't know how to declare class properties in Objective-C.

也许这很明显,但我不知道如何在 Objective-C 中声明类属性。

I need to cache per-class a dictionary and wonder how put it in the class.

我需要为每个班级缓存一个字典,并想知道如何将它放在班级中。

采纳答案by Andrew Grant

properties have a specific meaning in Objective-C, but I think you mean something that's equivalent to a static variable? E.g. only one instance for all types of Foo?

属性在 Objective-C 中具有特定含义,但我认为您的意思是等效于静态变量?例如,所有类型的 Foo 只有一个实例?

To declare class functions in Objective-C you use the + prefix instead of - so your implementation would look something like:

要在 Objective-C 中声明类函数,您可以使用 + 前缀而不是 - 这样您的实现将类似于:

// Foo.h
@interface Foo {
}

+ (NSDictionary *)dictionary;

// Foo.m
+ (NSDictionary *)dictionary {
  static NSDictionary *fooDict = nil;
  if (fooDict == nil) {
    // create dict
  }
  return fooDict;
}

回答by spooki

I'm using this solution:

我正在使用这个解决方案:

@interface Model
+ (int) value;
+ (void) setValue:(int)val;
@end

@implementation Model
static int value;
+ (int) value
{ @synchronized(self) { return value; } }
+ (void) setValue:(int)val
{ @synchronized(self) { value = val; } }
@end

And i found it extremely useful as a replacement of Singleton pattern.

我发现它作为单例模式的替代非常有用。

To use it, simply access your data with dot notation:

要使用它,只需使用点表示法访问您的数据:

Model.value = 1;
NSLog(@"%d = value", Model.value);

回答by Alex Nolasco

As seen in WWDC 2016/XCode 8 (what's new in LLVM session@5:05). Class properties can be declared as follows

如 WWDC 2016/XCode 8 中所见(LLVM 会话中的新内容@5:05)。类属性可以声明如下

@interface MyType : NSObject
@property (class) NSString *someString;
@end

NSLog(@"format string %@", MyType.someString);

Note that class properties are never synthesized

请注意,永远不会合成类属性

@implementation
static NSString * _someString;
+ (NSString *)someString { return _someString; }
+ (void)setSomeString:(NSString *)newString { _someString = newString; }
@end

回答by Jim Puls

If you're looking for the class-level equivalent of @property, then the answer is "there's no such thing". But remember, @propertyis only syntactic sugar, anyway; it just creates appropriately-named object methods.

如果您正在寻找类级别的 等价物@property,那么答案是“没有这样的东西”。但请记住@property,无论如何,这只是语法糖;它只是创建适当命名的对象方法。

You want to create class methods that access static variables which, as others have said, have only a slightly different syntax.

您想创建访问静态变量的类方法,正如其他人所说,这些静态变量的语法略有不同。

回答by Quentin

Here's a thread safe way of doing it:

这是一种线程安全的方法:

// Foo.h
@interface Foo {
}

+(NSDictionary*) dictionary;

// Foo.m
+(NSDictionary*) dictionary
{
  static NSDictionary* fooDict = nil;

  static dispatch_once_t oncePredicate;

  dispatch_once(&oncePredicate, ^{
        // create dict
    });

  return fooDict;
}

These edits ensure that fooDict is only created once.

这些编辑确保 fooDict 只创建一次。

From Apple documentation: "dispatch_once - Executes a block object once and only once for the lifetime of an application."

来自Apple 文档:“dispatch_once - 在应用程序的生命周期内只执行一次块对象。”

回答by berbie

As of Xcode 8 Objective-C now supports class properties:

从 Xcode 8 Objective-C 开始,现在支持类属性:

@interface MyClass : NSObject
@property (class, nonatomic, assign, readonly) NSUUID* identifier;
@end

Since class properties are never synthesised you need to write your own implementation.

由于类属性永远不会被合成,因此您需要编写自己的实现。

@implementation MyClass
static NSUUID*_identifier = nil;

+ (NSUUID *)identifier {
  if (_identifier == nil) {
    _identifier = [[NSUUID alloc] init];
  }
  return _identifier;
}
@end

You access the class properties using normal dot syntax on the class name:

您可以使用类名上的普通点语法访问类属性:

MyClass.identifier;

回答by mouviciel

Properties have values only in objects, not classes.

属性仅在对象中具有值,而不在类中。

If you need to store something for all objects of a class, you have to use a global variable. You can hide it by declaring it staticin the implementation file.

如果你需要为一个类的所有对象存储一些东西,你必须使用一个全局变量。您可以通过static在实现文件中声明它来隐藏它。

You may also consider using specific relations between your objects: you attribute a role of master to a specific object of your class and link others objects to this master. The master will hold the dictionary as a simple property. I think of a tree like the one used for the view hierarchy in Cocoa applications.

您还可以考虑使用对象之间的特定关系:您将主人的角色归因于您的类的特定对象,并将其他对象链接到该主人。主人将把字典作为一个简单的属性。我想到了一种类似于 Cocoa 应用程序中用于视图层次结构的树。

Another option is to create an object of a dedicated class that is composed of both your 'class' dictionary and a set of all the objects related to this dictionary. This is something like NSAutoreleasePoolin Cocoa.

另一种选择是创建一个专用类的对象,该对象由您的“类”字典和与该字典相关的所有对象组成。这有点像NSAutoreleasePool可可。

回答by Jean-Marie D.

Starting from Xcode 8, you can use the classproperty attribute as answered by Berbie.

从 Xcode 8 开始,您可以使用Berbie 回答的class属性属性。

However, in the implementation, you need to define both class getter and setter for the class property using a static variable in lieu of an iVar.

但是,在实现中,您需要使用静态变量代替 iVar 为类属性定义类 getter 和 setter。

Sample.h

样本.h

@interface Sample: NSObject
@property (class, retain) Sample *sharedSample;
@end

Sample.m

样本.m

@implementation Sample
static Sample *_sharedSample;
+ ( Sample *)sharedSample {
   if (_sharedSample==nil) {
      [Sample setSharedSample:_sharedSample];
   }
   return _sharedSample;
}

+ (void)setSharedSample:(Sample *)sample {
   _sharedSample = [[Sample alloc]init];
}
@end

回答by Pedro Borges

If you have many class level properties then a singleton pattern might be in order. Something like this:

如果您有许多类级别的属性,那么可能适合使用单例模式。像这样的东西:

// Foo.h
@interface Foo

+ (Foo *)singleton;

@property 1 ...
@property 2 ...
@property 3 ...

@end

And

// Foo.m

#import "Foo.h"

@implementation Foo

static Foo *_singleton = nil;

+ (Foo *)singleton {
    if (_singleton == nil) _singleton = [[Foo alloc] init];

    return _singleton;
}

@synthesize property1;
@synthesize property2;
@synthesise property3;

@end

Now access your class-level properties like this:

现在访问您的类级属性,如下所示:

[Foo singleton].property1 = value;
value = [Foo singleton].property2;

回答by jawad

[Try this solution it's simple] You can create a static variable in a Swift class then call it from any Objective-C class.

[试试这个解决方案,它很简单] 您可以在 Swift 类中创建一个静态变量,然后从任何 Objective-C 类中调用它。