2011-05-17 36 views
43

我新的目標C和正在讀一本書,叫做「視覺快速入門指南:Objective-C的」由史蒂芬Holzner的,購買PeachpitPress新聞目標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可變

這本書是錯的還是我做錯了什麼?

+4

這本書是完全錯誤的,也沒有在Objective-C類變量的概念。你可以像C那樣聲明靜態變量,但它們不屬於類(至少在語義上)。 – BoltClock 2011-05-17 19:10:20

回答

93

您在實現文件(.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靜態變量,可以通過類的實現訪問。

+11

如果「類變量」是一個對象(比如NSSet),需要初始化嗎? – Uri 2012-08-04 16:57:34

+0

@mipadi - 請爲我澄清。我不確定「類變量」的定義,因此我不明白爲什麼「它不是類變量」。在實現文件中聲明的靜態變量由類的所有實例共享,並且只能由該類的實例訪問。它不是一個「類變量」,因爲它不能被子類訪問?或者還有其他一些原因使你有區別?我真誠喜歡學習。 – 2013-10-12 19:18:29

+1

@ Chuck-Krutsinger由於沒有人回答過:類變量的概念與類方法(但是變量)相同,即可以在不創建類的實例的情況下訪問該變量,這正是一個什麼在實現中的靜態變量會做。他使用「類變量」這個術語的原因是因爲這就是問題所在,但它們不存在,因爲靜態已經提供了必要的功能。 – 2014-02-25 13:37:18

14

我見過關於Unix的一個Visual快速入門指南,它吸引了很大的時間。至少從樣本來看,這似乎並沒有好多少。建立在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。它是免費的,這是一個很好的閱讀。

6

您應該在放置@implementation的.m文件中聲明該變量。所以,

#import "TheClass.h" 

static int count; 

@implementation 

... 

@end 

重要的是要注意,Objective-C實際上並不支持類變量。但是你可以用靜態變量來模擬它們,就像我們在這裏做的那樣。

9

如果「類變量」需要的不只是瑣碎的初始化的更多,使用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; 
}