數值、結構、字串指標封裝成物件

數值、結構、字串指標封裝成物件

Objective-C語言特性容許在程式中使用C語言語法,因此程式中會看到C語言的數值類型(int,float…)、結構(struct)、字串指標(char *),但有些物件功能的method中只允許傳入物件,像是NSArray宣告,如果還是硬要將這些C語言類型傳入NSArray,那你必需要將原本的值類型、結構、指標封裝成物件類型,之後使用時再裝封裝物件轉成數值、結構、指標。

NSNumber

數值封裝

一般C語法數值封裝在Objective-C中已經提供很完善的方法,NSNumber物件使用上可能沒發覺它就是屬於這類的,它將數值封裝入物件中,需要時再利用對應的method取得數值。

封裝

NSNumber提供的方式有兩種,一種帶有宣告物件及初始化的方式,另一種是使用它提供的單例方法直接產生新的物件。

宣告方式:

//-----------start-----------
        NSNumber *num = [[NSNumber alloc] initWithInt:1];
        NSArray *array = [[NSArray alloc] initWithObjects:num, nil];
        NSLog(@"%@",array);
//------------end------------

單例方法:

//-----------start-----------
        NSNumber *num = [NSNumber numberWithInt:1];
        NSArray *array = [NSArray arrayWithObjects:num, nil];
        NSLog(@"%@",array);
//------------end------------

還原

將封裝入再取出的方式更簡單,使用它提供的方法,在這要提到一個重點,NSNumber封裝後,取出值時可以利用它的方法來間接的轉換成你要的數值類型:

//-----------start-----------
        NSNumber *num = [NSNumber numberWithInt:1];
        float floatNum = [num floatValue];
        NSLog(@"%f",floatNum);
//------------end------------

支援的類型:

- (char)charValue;
- (unsigned char)unsignedCharValue;
- (short)shortValue;
- (unsigned short)unsignedShortValue;
- (int)intValue;
- (unsigned int)unsignedIntValue;
- (long)longValue;
- (unsigned long)unsignedLongValue;
- (long long)longLongValue;
- (unsigned long long)unsignedLongLongValue;
- (float)floatValue;
- (double)doubleValue;
- (BOOL)boolValue;
- (NSInteger)integerValue;
- (NSUInteger)unsignedIntegerValue;
- (NSString *)stringValue;

上面提供的有注意到stringValue方法嗎?沒錯!它提供字串輸出,意指我們能利用它將數值轉字串:

//-----------start-----------
        NSNumber *num = [NSNumber numberWithFloat:1.123f];
        NSLog(@"%@",[num stringValue]);
//------------end------------


NSValue

C語言中除了數值外,還有比較特別的宣告,像結構(struct)、字串指標(char *),這種類型能將它封裝起來嗎?當然是可以,Objective-C另外提供物件NSValue提供封裝此類的宣告,特點是以指標位址的方式來保存。

結構封裝

封裝

//-----------start-----------
        typedef struct {
            NSInteger year;
            NSInteger month;
            NSInteger day;
        } Date;
        //自訂Date名稱結構
        Date myDate;
        myDate.year = 1979;
        myDate.month = 12;
        myDate.day = 3;
        //將myDate封裝成NSValue物件
        NSValue* myDateValue = [NSValue valueWithBytes: &myDate objCType: @encode(Date)];

//------------end------------

還原

//-----------start-----------
        typedef struct {
            NSInteger year;
            NSInteger month;
            NSInteger day;
        } Date;
        //自訂Date名稱結構
        Date myDate;
        myDate.year = 1979;
        myDate.month = 12;
        myDate.day = 3;
        //將myDate封裝成NSValue物件
        NSValue* myDateValue = [NSValue valueWithBytes: &myDate objCType: @encode(Date)];
        //宣告myDateOriginal為Data結構
        Date myDateOrginal;
        //利用getValue取得整個結構位址並傳入myDateOriginal
        [myDateValue getValue:&myDateOriginal];

        NSLog(@"%ld %ld %ld ",myDateOriginal.year,myDateOriginal.month,myDateOriginal.day);
//------------end------------

字串指標封裝

封裝

//-----------start-----------
        char* charString = "Hello Danny";
        NSValue* charValue = [NSValue valueWithBytes: &charString objCType: @encode(char**)];
//------------end------------

還原

//-----------start-----------
        char* charString = "Hello everyone";
        NSValue* charValue = [NSValue valueWithBytes: &charString objCType: @encode(char**)];
        char* charStringOriginal;
        [charValue getValue:&charStringOriginal];
        NSLog(@"%s",charStringOriginal);
//------------end------------