【问题标题】:Objective C static class variablesObjective C 静态类变量
【发布时间】:2011-08-27 12:11:50
【问题描述】:

我是 Objective C 的新手,正在阅读 Peachpit Press 的 Steven Holzner 撰写的名为“Visual Quickstart Guide: Objective-C”的书

在第 6 章:面向对象编程中,有一节叫做使用类变量,他写道:

您可以创建类变量以用于 你的类,但有一个障碍:每个对象 该类的共享相同的变量,所以 如果一个对象改变了一个类变量,那 为所有对象更改变量。你创造 使用 static 关键字的类变量。 类变量通常很有用:例如, 您可以使用类变量来跟踪 创建的特定类的对象数 在一个程序中。您将在此任务中执行此操作。

并说输入以下代码:

#import <stdio.h>
#import <Foundation/NSObject.h>
@interface TheClass: NSObject
static int count; //error: cannot declare variable inside @interface or @protocol
+(int) getCount;
@end
...

这段代码在 Xcode 4 中给我一个错误:

不能在@interface 或@protocol 中声明变量

是书错了还是我做错了什么?

【问题讨论】:

  • 书上完全错了,Objective-C中没有类变量的概念。您可以像在 C 中那样声明静态变量,但它们与类无关(至少在语义上不是)。

标签: objective-c xcode xcode4


【解决方案1】:

如果“类变量”需要的不仅仅是简单的初始化,请使用dispatch_once

@interface Foo ()
+ (Foo *)singleton;
@end

+ (Foo *)singleton {
    static Foo *_singleton;
    static dispatch_once_t oncePredicate;

    dispatch_once(&oncePredicate, ^{
        _singleton = [[Foo alloc] init];
    });

    return _singleton;
}

【讨论】:

    【解决方案2】:

    我看过一个关于 Unix 的可视化快速入门指南,它很花时间。至少从样本来看,这个似乎并没有好多少。在 Objective-C 中创建类变量的正确方法是这样的:

    // Counted.h
    @interface Counted : NSObject
    
    + (NSUInteger) numberOfInstances;
    
    @end
    
    // Counted.m
    #import "Counted.h"
    
    static NSUInteger instances = 0;
    
    @implementation Counted
    
    - (id) init {
        …
        instances++;
        …
    }
    
    - (void) dealloc {
        instances--;
    }
    
    + (NSUInteger) numberOfInstances {
        return instances;
    }
    
    @end
    

    这实际上是一个静态变量,而不是真正的类变量。但是无论如何你都不应该太担心类变量,它们通常表明你做错了。 (我有点过于简单化了,但不多。)

    如果您正在寻找一本不错的 Objective-C 书籍,请阅读 the one by Apple。它是免费的,而且是一本好书。

    【讨论】:

      【解决方案3】:

      你应该在 .m 文件中声明变量,@implementation 被放置在其中。所以,

      #import "TheClass.h"
      
      static int count;
      
      @implementation
      
      ...
      
      @end
      

      需要注意的是,Objective-C 实际上并不支持类变量。但是您可以使用静态变量来模拟它们,就像我们在这里所做的那样。

      【讨论】:

        【解决方案4】:

        您在实现文件(.m 文件)中声明静态变量。这应该有效:

        // TheClass.h
        @interface TheClass : NSObject
        + (int)count;
        @end
        
        // TheClass.m
        static int theCount = 0;
        
        @implementation TheClass
        + (int) count { return theCount; }
        @end
        

        它本身不是一个类变量; Objective-C 没有类变量的概念。但是,与用于检索此变量的类方法相结合,它的功能类似于类变量。然而,它实际上只是一个类的实现可以访问的 C 静态变量。

        【讨论】:

        • 如果“类变量”是一个需要初始化的对象(比如 NSSet)怎么办?
        • @mipadi - 请为我澄清。我不确定“类变量”的定义,因此不确定我是否理解“它不是类变量”的原因。在实现文件中声明的静态变量由该类的所有实例共享,并且只能由该类的实例访问。它不是“类变量”,因为子类无法访问它吗?还是有其他原因让您做出区分?我真的很想学习。
        • @Chuck-Krutsinger 正如没有其他人回答的那样:类变量的概念与类方法(但变量)相同,即无需创建实例即可访问的变量类,这正是实现中的静态变量所做的。他使用术语“类变量”的原因是因为这就是问题所在,但它们不存在,因为静态已经提供了必要的功能。
        • 对类使用 ''+ (void)initialize''(Java 或 C# 中的静态构造函数的类似物)
        • 嘿,我前段时间做了一个要点,不兼容 ARC,但它实际上可以通过使用分配方法并指定强或弱引用在 ARC 中使用。 gist.github.com/darionco/03649feeee57f86fee3f
        猜你喜欢
        • 2010-11-06
        • 1970-01-01
        • 2012-01-26
        • 2012-07-14
        • 1970-01-01
        • 1970-01-01
        • 2013-04-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多