数值、结构、字串指标封装成物件

数值、结构、字串指标封装成物件

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------------