当前位置:  开发笔记 > 前端 > 正文

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

如何解决《如何在Objective-C中声明类级属性?》经验,为你挑选了8个好方法。

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

我需要为每个类缓存一个字典,并想知道如何将它放入类中.



1> Andrew Grant..:

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

要在Objective-C中声明类函数,请使用+前缀而不是 - 所以您的实现看起来像:

// Foo.h
@interface Foo {
}

+ (NSDictionary *)dictionary;

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


行static NSDictionary*fooDict = nil; 只会执行一次!即使在多次调用的方法中,如果存在具有此名称的静态变量,则将忽略带有关键字static的声明(以及在此示例中为初始化).
这是正确的吗?不会将fooDict设置为nil,因为字典方法的第一行总是导致每次都重新创建字典?
http://stackoverflow.com/questions/554969/using-static-keyword-in-objective-c-when-defining-a-cached-variable
看看Alex Nolasco的答案,自Xcode 8发布以来可以使用类属性:http://stackoverflow.com/a/37849467/6666611
@ BenC.R.Leggiero是的,绝对的.`.`-访问器语法与Objective-C中的属性无关,它只是任何返回内容而不带任何args的方法的编译快捷方式.在这种情况下,我更喜欢它 - 我个人更喜欢`.`语法用于客户端代码打算获取某些内容的任何用法,而不执行操作_(即使实现代码可能创建一次,或执行副作用操作) _.大量使用`.`语法也会产生更易读的代码:`[...]的存在意味着当提取使用`.`语法时,正在做一些重要的事情.

2> spooki..:

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

@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

我发现它作为Singleton模式的替代品非常有用.

要使用它,只需使用点符号访问您的数据:

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


@ToddLehman`self`是[收到消息的对象](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html#//apple_ref/doc/uid/TP40011210-CH4-SW5).因为[类也是对象](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/DefiningClasses/DefiningClasses.html#//apple_ref/doc/uid/TP40011210-CH3-SW18 ),在这种情况下,`self`表示`Model`
为什么getter需要`@ synchronized`?
真的很酷.但是,在类方法中,"自我"究竟是什么意思呢?
这很酷,但...... 10行代码只是为了创建1个静态成员?什么是黑客.Apple应该只是将其作为一项功能.

3> Alex Nolasco..:

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

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

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

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

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


也许应该明确指出这对于访问器声明来说是_only_ sugar.如您所述,该属性未被合成:仍然必须声明和使用(`static`)变量,并且显式实现这些方法,就像之前一样.Dot语法也已经在以前工作过了.总而言之,这听起来比实际更重要.
重要的是这意味着您可以在不使用()的情况下从Swift代码访问单例,并且按照约定删除类型后缀.例如XYZMyClass.shared(Swift 3)而不是XYZMyClass.sharedMyClass()

4> Jim Puls..:

如果你正在寻找等级的等级@property,那么答案就是"没有这样的东西".但请记住@property,无论如何,它只是语法糖; 它只是创建适当命名的对象方法.

您想要创建访问静态变量的类方法,正如其他人所说的那样,静态变量的语法略有不同.


@ZakyGerman你可以!`UIDevice.currentDevice.identifierForVendor`适合我.

5> Quentin..:

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

// 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;
}

这些编辑确保fooDict仅创建一次.

来自Apple文档:"dispatch_once - 在应用程序的生命周期内执行一次且仅执行一次块对象."


dispatch_once代码是不相关的,因为静态NSDictionary可以在+(NSDictionary*)字典方法的第一行初始化,因为它是静态的,它只会被初始化一次吗?

6> berbie..:

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

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

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

@implementation MyClass
static NSUUID*_identifier = nil;

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

您可以使用类名称上的常规点语法访问类属性:

MyClass.identifier;



7> mouviciel..:

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

如果需要为类的所有对象存储某些内容,则必须使用全局变量.您可以通过static在实现文件中声明它来隐藏它.

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

另一种选择是创建一个专用类的对象,该对象由"类"字典和与该字典相关的所有对象组成.这就像NSAutoreleasePool在Cocoa中.



8> Jean-Marie D..:

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

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

样本

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

样例

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

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

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有