2014年3月20日 星期四

@property 指令識別屬性

在介面區段使用@property指令識別屬性,編譯器會自動為程式產生setter以及getter這兩個方法。
例如;
下面的介面區段,使用@property指令識別屬性,宣告兩個setter以及getter方法,分別為numberOne、numberTwo。另外,宣告一個整數變數numberThree。在做這樣的宣告時,編譯器會另外產生兩個整數變數_numberOne、_numberTwo。

#import <Foundation/Foundation.h>

@interface Number : NSObject
{
    int numberThree;
}

@property int numberOne, numberTwo;

- (void)printNumber;
- (void)setNumberThree:(int)number;


@end

在下面的實作區段中,實作了在介面區段中的兩個方法,分別為setNumberThree以及printNumber。在printNumber中,使用了getter方法self.numberOne以及self.numberTwo。如果不用點運算子(﹒),也可以使用實體方法,即[self numberOne]以及[self numberTwo]表示。我們也把編譯器產生的兩個整數變數_numberOne、_numberTwo的值印出來看看結果。setNumberThree是我們為整數變數numberThree產生的setter方法

#import "Number.h"

@implementation Number

- (void)setNumberThree:(int)number
{
    numberThree = number;
}

- (void)printNumber
{
    NSLog(@"numberOne = %d, numberTwo = %d, numberThree = %d, _numberOne =                  %d, _numberTwo = %d", self.numberOne, self.numberTwo, numberThree,                  _numberOne, _numberTwo);
}

@end

在下面的主程式中,使用編譯器產生的setter方法為變數_numberOne, _numberTwo設定整數值,分別為3與5。setter方法也可以用點運算子(﹒)表示,即cal.numberOne = 3、cal.numberTwo = 5。

#import <Foundation/Foundation.h>
#import "Number.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        Number *cal = [[Number alloc]init];
        [cal setNumberOne:3];
        [cal setNumberTwo:5];
        [cal setNumberThree:10];
        [cal printNumber];
    }
    return 0;
}
主控台輸出的結果如下;
2014-03-20 15:19:51.049 Calculation[1261:303] numberOne = 3, numberTwo = 5, numberThree = 10, _numberOne = 3, _numberTwo = 5
Program ended with exit code: 0

2014年3月19日 星期三

for 迴圈的區域變數

原則上,區域變數沒有預設初始值,因此必需在使用之前加以指定。例如;

下面的程式中,在for迴圈,區域變數index應該宣告初始值,但是沒有宣告。

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        for (int index; index < 10; index++) {
            NSLog(@"index = %d", index);
        }
        // insert code here...
        NSLog(@"Hello, World!");
        
    }
    return 0;

}

使用for迴圈在控制台輸出區域變數index的值,因為區域變數index沒有宣告初始值,原則上每次index輸出應該為非預期的值。但是,我在XCode 5.1測試好幾次,顯示出來的結果均為如下所示:
2014-03-19 10:12:22.971 forloop[679:303] index = 0
2014-03-19 10:12:22.973 forloop[679:303] index = 1
2014-03-19 10:12:22.974 forloop[679:303] index = 2
2014-03-19 10:12:22.974 forloop[679:303] index = 3
2014-03-19 10:12:22.975 forloop[679:303] index = 4
2014-03-19 10:12:22.975 forloop[679:303] index = 5
2014-03-19 10:12:22.976 forloop[679:303] index = 6
2014-03-19 10:12:22.976 forloop[679:303] index = 7
2014-03-19 10:12:22.977 forloop[679:303] index = 8
2014-03-19 10:12:22.977 forloop[679:303] index = 9
2014-03-19 10:12:22.978 forloop[679:303] Hello, World!

Program ended with exit code: 0

顯然編譯器自動給予初始值0,如果原本想要的初始值是1,那麼結果就非如預期了。
無論如何,在for迴圈中,區域變數一定要有初始值,否則程式會出現不可預期的結果。

2014年3月16日 星期日

取小數點位數的方法(一)

在Objective-C中,宣告float型態的變數,可用來儲存包含小數點的數值。例如;

float fValueOne  = 881.79;
float fValueTwo = 1972.51828;

如果把以上兩個數值相加之後,只想取小數點後兩位數,該如何處理呢?
我們可以利用NSString的類別方法stringWithFormat:來處理這個數值,方法如下;

[NSString stringWithFormat:@"1.2f", fValueOne + fValueTwo];

使用此類別方法取小數點後兩位數之後,產生的是NSString型態的物件,若需要繼續使用float資料型態做後續數學運算,則必須把NSString型態的物件轉換成float資料型態,可以運用NSString物件的方法floatValue來達成。

float fValue = [[NSString stringWithFormat:@"1.2f", fValueOne + fValueTwo]floatValue];

用NSLog來顯示fValueOne的值,NSLog(@"fValueOne = %f", fValueOne);
輸出的結果為fValueOne = 881.789978,輸出的數值與實際設定值881.79並不一致。產生此種錯誤原因在於電腦內部數值處理所造成。