2013年8月9日 星期五

Objective-C Variables

Local Variables 

區域變數只存活於它所在的區塊內,能存取它的範圍也在那個區域,而程式執行完那段後,變數即消失。

-(void)saveMoney
{
     int capital = 0;
     capital++;
     NSLog(@"Capital : %d",capital);
}
每當saveMoney這個方法被呼叫時,變數在此初始化並賦值,然後加一,而在這個區域中,可以存取到capital變數,但是不管執行saveMoney這個方法幾次,Capital永遠都是1,因為方法執行完後,變數capital就消失了。如果要保留此變數所存的值,勢必要使用別種方法。

static

-(void)saveMoney
{
     static int capital = 0;
     capital++;
     NSLog(@"Capital : %d",capital);
}
如果我在變數前面加上關鍵字 static,那麼這個變數只會被初始化並賦值一次,並不會每次呼叫此方法時都重複作一次,故第一次執行saveMoney時,initialize capital and add 1 ,第二次加一,第三次再加一,一直下去。

不過這樣的寫法,capital只能在saveMoney中被存取,把它移到implement外,這樣在implement中的其他方法也都可以存取它囉,邏輯上也更清楚。

#import "Cheapskate.h"
static int capital;
@implemention Cheapskate
-(void)saveMoney
{
     static int capital = 0;
     capital++;
}

-(void)showMoney
{
     NSLog(@"Capital : %d",capital);
}
@end

Instance  Variable Scope

@protected      self and subclass (default)
@private        self
@public         any other class
如果是public instance variable,可以使用 pointer operator ( ->)

Global Variable

在程式的開始,任何方法、類別宣告(@interface)、struct declaration之外,可以宣告與定義全域變數,變數的名稱前面慣例加上g,表示全域。全域變數的使用要很小心,除錯時很難找,儘量少用,如果真的要用,名稱要取的好一些,建議前面加上g。

int gVariable = 0 ;


如果只有declaration沒有definition的話,基礎型別用預設值,int 0,objective-C object則是nil,如果是複雜的definition,無法在宣告的同時也定義,可以在其他地方作定義,例如,main()、application delegate init method, applicationDidFinishLaunching method ..

NSArray *array = [[NSArray alloc] initWithObjects:@"one",@"two",nil]; 
// Initializer element is not a compile-time constant
如果在 global variable 前面加上 static ,那這個變數的可見域就只限於此 implementation file,不再是全域變數了,變成了像是 class variable

External Variables

外部變數,顧名思義就是宣告在外的變數,:(,通常和全域變數一起用,告訴complier這個變數已經在外部宣告並定義過了,我在這個檔案或區域中要使用。記得,在使用extern 時,不可以再定義。

extern int gVariable = 10; // error

const 

無法再修改值的變數,這意味著在開始的時候就必須給定值,良好的編程習慣是,當你知道某個變數的值不應該再變動時,就加上const,別人也一目了然。

const double pi = 3.14159;

volatile

揮發易變的變數,使用的原因是為了預防編譯器把變數最佳化,以下是wiki的例子:

static int foo;
void bar(void) {
    foo = 0;
 
    while (foo != 255)
         ;
}
similar to this
void bar_optimized(void) {
    foo = 0;
 
    while (true)
         ;
}
foo變數有可能在外部會進行修改(例如:delegate),加上volatile 避免編譯器的最佳化。
static volatile int foo;
 
void bar (void) {
    foo = 0;
 
    while (foo != 255)
        ;
}

沒有留言: