美文网首页
系列:iOS开发-NSNumber、NSData

系列:iOS开发-NSNumber、NSData

作者: spicyShrimp | 来源:发表于2017-09-20 15:49 被阅读123次

    系列:iOS开发-NSNumber、NSData

    这两个类型准备一起讲,
    因为NSNumber比较简单,
    首先将NSNumber,
    我在之前就有说过在数组里面在字典里面是没有办法存储C语言中的那些基础类型的,比如int、比如float...
    那么我们又想存储这些值 我们怎么办呢?
    OC给我们封装了一个NSNumber的类
    介绍就是:NSNumber:专门用来装基础类型的对象,把整型、单精度、双精度、字符型等基础类型存储为对象

    基础类型->对象类型
    那么就满足OC的语法,数组就可以存储了
    所以说,NSNumber还是一个数...

    我们简单看看这个类,

    创建:

    //NSNumber
            //initWithChar:
            NSNumber *num1 = [[NSNumber alloc]initWithChar:'a'];
            NSLog(@"num1 = %@",num1);
            
            //initWithShort:
            NSNumber *num2= [[NSNumber alloc]initWithShort:1];
            NSLog(@"num2 = %@",num2);
            
            NSNumber *num3= [[NSNumber alloc]initWithInt:1];
            NSLog(@"num3 = %@",num3);
            
            //initWithLong:
            NSNumber *num4 = [[NSNumber alloc]initWithLong:10000000000];
            NSLog(@"num4 = %@",num4);
            
            //initWithLongLong:
            NSNumber *num5 = [[NSNumber alloc]initWithLongLong:1000000000000000000];
            NSLog(@"num5 = %@",num5);
            
            //initWithFloat:
            NSNumber *num6 = [[NSNumber alloc]initWithFloat:M_PI];
            NSLog(@"num6 = %@",num6);
            
            //initWithDouble:
            NSNumber *num7 = [[NSNumber alloc]initWithDouble:999999999999];
            NSLog(@"num7 = %@",num7);
            
            //initWithBool:
            NSNumber *num8 = [[NSNumber alloc]initWithBool:YES];
            NSLog(@"num8 = %@",num8);
            
            //initWithInteger:
            NSNumber *num9 = [[NSNumber alloc]initWithInteger:1];
            NSLog(@"num9 = %@",num9);
            
            NSNumber *num10 = @(111);
            NSLog(@"num10 = %@",num10);
            
            //numberWithChar:
            NSNumber *num11 = [NSNumber numberWithChar:'b'];
            NSLog(@"num11 = %@",num11);
            
            //numberWithShort:
            NSNumber *num12 = [NSNumber numberWithShort:1];
            NSLog(@"num12 = %@",num12);
            
            //numberWithInt:
            NSNumber *num13 = [NSNumber numberWithInt:1];
            NSLog(@"num13 = %@",num13);
            
            //numberWithLong:
            NSNumber *num14 = [NSNumber numberWithLong:1000000000];
            NSLog(@"num14 = %@",num14);
            
            //numberWithLongLong:
            NSNumber *num15 = [NSNumber numberWithLongLong:10000000000000000];
            NSLog(@"num15 = %@",num15);
            
            //numberWithFloat:
            NSNumber *num16 = [NSNumber numberWithFloat:M_PI];
            NSLog(@"num16 = %@",num16);
            
            //numberWithDouble:
            NSNumber *num17 = [NSNumber numberWithDouble:999999999];
            NSLog(@"num17 = %@",num17);
            
            //numberWithBool:
            NSNumber *num18 = [NSNumber numberWithBool:YES];
            NSLog(@"num18 = %@",num18);
            
            //numberWithInteger:
            NSNumber *num19 = [NSNumber numberWithInteger:1];
            NSLog(@"num19 = %@",num19);
    
    

    我去....本来说简单,,但是所有的都写出来,真累.........

    常用方法
    我们看看他有那些,然后一个一个来,

    @property (readonly) char charValue;
    @property (readonly) unsigned char unsignedCharValue;
    @property (readonly) short shortValue;
    @property (readonly) unsigned short unsignedShortValue;
    @property (readonly) int intValue;
    @property (readonly) unsigned int unsignedIntValue;
    @property (readonly) long longValue;
    @property (readonly) unsigned long unsignedLongValue;
    @property (readonly) long long longLongValue;
    @property (readonly) unsigned long long unsignedLongLongValue;
    @property (readonly) float floatValue;
    @property (readonly) double doubleValue;
    @property (readonly) BOOL boolValue;
    @property (readonly) NSInteger integerValue NS_AVAILABLE(10_5, 2_0);
    @property (readonly) NSUInteger unsignedIntegerValue NS_AVAILABLE(10_5, 2_0);
    
    @property (readonly, copy) NSString *stringValue;
    
    - (NSComparisonResult)compare:(NSNumber *)otherNumber;
    
    - (BOOL)isEqualToNumber:(NSNumber *)number;
    
    - (NSString *)descriptionWithLocale:(nullable id)locale;
    

    首先的都是value 获取都原始的基础数据类型
    然后是比较,
    OK
    我们一个一个试试

    NSLog(@"%c",[num1 charValue]);
            
            NSLog(@"%d",[num2 shortValue]);
            
            NSLog(@"%d",[num3 intValue]);
            
            NSLog(@"%ld",[num4 longValue]);
            
            NSLog(@"%lld",[num5 longLongValue]);
            
            NSLog(@"%f",[num6 floatValue]);
            
            NSLog(@"%f", [num7 doubleValue]);
            
            NSLog(@"%d",[num8 boolValue]);
            
            NSLog(@"%ld",[num9 integerValue]);
            
            NSLog(@"%@",[num10 stringValue]);
            
            NSLog(@"%d",[num10 isEqualToNumber:num9]);
            
            NSLog(@"%ld",(long)[num10 compare:num9]);
    

    当然,并不是只能返回原始的基础类型,比如我原来的是float ,但是我用intValue会怎么样呢?没有错,强制转换了,转成int类型的数据了, 是的所以他还有强制转换的作用哟..

    至于isEqualToNumber和compare都是比较两个对象的大小或者是否相等等问题

    都是字面上的理解 超级简单....

    所以NSNumber可以说的也不多,我们就这么随随便便的就基本掌握了一个类,
    是不是很有成就感,

    那么我们接下来就再看一个稍微复杂的类NSData
    为什么说复杂了呢?

    /****************   Immutable Data      ****************/
    
    @interface NSData : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>
    

    从定义上看,它也就是集成NSData的一个类型嘛....

    + (instancetype)data;
    + (instancetype)dataWithBytes:(nullable const void *)bytes length:(NSUInteger)length;
    + (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
    + (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
    + (nullable instancetype)dataWithContentsOfFile:(NSString *)path options:(NSDataReadingOptions)readOptionsMask error:(NSError **)errorPtr;
    + (nullable instancetype)dataWithContentsOfURL:(NSURL *)url options:(NSDataReadingOptions)readOptionsMask error:(NSError **)errorPtr;
    + (nullable instancetype)dataWithContentsOfFile:(NSString *)path;
    + (nullable instancetype)dataWithContentsOfURL:(NSURL *)url;
    - (instancetype)initWithBytes:(nullable const void *)bytes length:(NSUInteger)length;
    - (instancetype)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length;
    - (instancetype)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b;
    - (instancetype)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length deallocator:(nullable void (^)(void *bytes, NSUInteger length))deallocator NS_AVAILABLE(10_9, 7_0);
    - (nullable instancetype)initWithContentsOfFile:(NSString *)path options:(NSDataReadingOptions)readOptionsMask error:(NSError **)errorPtr;
    - (nullable instancetype)initWithContentsOfURL:(NSURL *)url options:(NSDataReadingOptions)readOptionsMask error:(NSError **)errorPtr;
    - (nullable instancetype)initWithContentsOfFile:(NSString *)path;
    - (nullable instancetype)initWithContentsOfURL:(NSURL *)url;
    - (instancetype)initWithData:(NSData *)data;
    + (instancetype)dataWithData:(NSData *)data;
    

    我们看下它的初始化和赋值等...
    我们会发现一个bytes
    这个又是什么鬼?其实就是这个东西
    Byte byte[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
    或者Byte byte2[] = {0x01,0x02};
    是的,就是个比特数组, 这玩意又回到了C的时候了好像,如果C语言没有学好,咋一看都会吓一跳,后面还有什么length?这个怎么算?对了 sizeof(byte)
    好吧,这些都吓不到你,那么为什么我还说稍微复杂呢?那就是这个数据的性质吧,data打印出来,那就是很对什么都看不懂的数据或者一堆数字,
    是的,你想到了编码ASCII、UTF8、BASE64... 没有错,这还涉及到编码,如果编码错了那就毫无意义...
    光说好像没有什么感觉
    那就用例子说话,
    首先是创建

    //NSData
            //init
            NSData *data1 = [[NSData alloc]init];
            NSLog(@"data1 = %@",data1);
            
            //initWithBytes:length:
            Byte mybyte[] = {0x01,0x02,0x03};
            NSData *data2 = [[NSData alloc]initWithBytes:mybyte length:sizeof(mybyte)];
            NSLog(@"data2 = %@",data2);
            
            //dataWithData:
            NSData *data3 = [NSData dataWithData:data2];
            NSLog(@"data3 = %@",data3);
    

    没啥可以说的,那么该说的是什么呢?
    没有错,就是NSData到各种类型的转换,因为我们很多时候拿着NSData没有什么用,因为不是具体的方便操作的类型....
    首先我们看看转码的类型枚举

    typedef NSUInteger NSStringEncoding;
    NS_ENUM(NSStringEncoding) {
        NSASCIIStringEncoding = 1,      /* 0..127 only */
        NSNEXTSTEPStringEncoding = 2,
        NSJapaneseEUCStringEncoding = 3,
        NSUTF8StringEncoding = 4,
        NSISOLatin1StringEncoding = 5,
        NSSymbolStringEncoding = 6,
        NSNonLossyASCIIStringEncoding = 7,
        NSShiftJISStringEncoding = 8,          /* kCFStringEncodingDOSJapanese */
        NSISOLatin2StringEncoding = 9,
        NSUnicodeStringEncoding = 10,
        NSWindowsCP1251StringEncoding = 11,    /* Cyrillic; same as AdobeStandardCyrillic */
        NSWindowsCP1252StringEncoding = 12,    /* WinLatin1 */
        NSWindowsCP1253StringEncoding = 13,    /* Greek */
        NSWindowsCP1254StringEncoding = 14,    /* Turkish */
        NSWindowsCP1250StringEncoding = 15,    /* WinLatin2 */
        NSISO2022JPStringEncoding = 21,        /* ISO 2022 Japanese encoding for e-mail */
        NSMacOSRomanStringEncoding = 30,
    
        NSUTF16StringEncoding = NSUnicodeStringEncoding,      /* An alias for NSUnicodeStringEncoding */
    
        NSUTF16BigEndianStringEncoding = 0x90000100,          /* NSUTF16StringEncoding encoding with explicit endianness specified */
        NSUTF16LittleEndianStringEncoding = 0x94000100,       /* NSUTF16StringEncoding encoding with explicit endianness specified */
    
        NSUTF32StringEncoding = 0x8c000100,                   
        NSUTF32BigEndianStringEncoding = 0x98000100,          /* NSUTF32StringEncoding encoding with explicit endianness specified */
        NSUTF32LittleEndianStringEncoding = 0x9c000100        /* NSUTF32StringEncoding encoding with explicit endianness specified */
    }
    

    是不是眼花缭乱了?

    没有错,如果用的编码方式不一样,结果就不一样,就不是你想要的
    比如你看看


    这里写图片描述

    结果就有的不一样...当然这个是最简单的例子,我们是需要自实际中选择合适的编码规则的,所以也不需要太过担心...

    //常用转换
            //NSData->NSString
            NSString *str1 = [[NSString alloc] initWithData:data3 encoding:NSUTF16StringEncoding];
            NSLog(@"%@",str1);
            
            NSString *str2 = [[NSString alloc] initWithData:data3 encoding:NSUTF8StringEncoding];
            NSLog(@"%@",str2);
            
            //NSString->NSData
            NSString *str3 = @"1234abcd";
            NSData *date4 = [str3 dataUsingEncoding: NSUTF8StringEncoding];
            NSLog(@"date4 = %@",date4);
            
            //NSData->Byte数组
            NSString *str4 = @"1234567890";
            NSData *date5 = [str4 dataUsingEncoding: NSUTF8StringEncoding];
            Byte *byte2 = (Byte *)[date5 bytes];
            for(int i=0;i<[date5 length];i++){
                printf("byte2 = %d\n",byte2[i]);
            }
            
            //Byte数组->NSData
            Byte byte3[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
            NSData *data6 = [[NSData alloc] initWithBytes:byte3 length:sizeof(byte3)];
            NSLog(@"data6 = %@",data6);
            
            //Byte数组->16进制数
            Byte *bytes = (Byte *)[data6 bytes];
            NSString *hexStr=@"";
            for(int i=0;i<[data6 length];i++)
            {
                NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff]; ///16进制数
                if([newHexStr length]==1)
                    hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
                else
                    hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
            }
            NSLog(@"bytes 的16进制数为:%@",hexStr);
            
            
            //16进制数->Byte数组
            /// 将16进制数据转化成Byte 数组
            NSString *hexString = @"3e435fab9c34891f"; //16进制字符串
            int j=0;
            Byte bytes1[128];
            ///3ds key的Byte 数组, 128位
            for(int i=0;i<[hexString length];i++)
            {
                int int_ch;  /// 两位16进制数转化后的10进制数
                
                unichar hex_char1 = [hexString characterAtIndex:i]; ////两位16进制数中的第一位(高位*16)
                int int_ch1;
                if(hex_char1 >= '0' && hex_char1 <='9')
                    int_ch1 = (hex_char1-48)*16;   //// 0 的Ascll - 48
                else if(hex_char1 >= 'A' && hex_char1 <='F')
                    int_ch1 = (hex_char1-55)*16; //// A 的Ascll - 65
                else
                    int_ch1 = (hex_char1-87)*16; //// a 的Ascll - 97
                i++;
                
                unichar hex_char2 = [hexString characterAtIndex:i]; ///两位16进制数中的第二位(低位)
                int int_ch2;
                if(hex_char2 >= '0' && hex_char2 <='9')
                    int_ch2 = (hex_char2-48); //// 0 的Ascll - 48
                else if(hex_char1 >= 'A' && hex_char1 <='F')
                    int_ch2 = hex_char2-55; //// A 的Ascll - 65
                else
                    int_ch2 = hex_char2-87; //// a 的Ascll - 97
                
                int_ch = int_ch1+int_ch2;
                NSLog(@"int_ch=%d",int_ch);
                bytes[j] = int_ch;  ///将转化后的数放入Byte数组里
                j++;
            }
            NSData *newData = [[NSData alloc] initWithBytes:bytes1 length:sizeof(bytes1)];
            NSLog(@"newData=%@",newData);
    

    总之由于数据类型的关系,NSData有时候需要做位运算,这些在遇到的时候再说吧.当然有的人可能几年都遇不到....
    至于可变data------ NSMutableData就简单的看看方法就行了,大家可以自己去尝试看看

    - (void)appendBytes:(const void *)bytes length:(NSUInteger)length;
    - (void)appendData:(NSData *)other;
    - (void)increaseLengthBy:(NSUInteger)extraLength;
    - (void)replaceBytesInRange:(NSRange)range withBytes:(const void *)bytes;
    - (void)resetBytesInRange:(NSRange)range;
    - (void)setData:(NSData *)data;
    - (void)replaceBytesInRange:(NSRange)range withBytes:(nullable const void *)replacementBytes length:(NSUInteger)replacementLength;
    

    首先是追加bytes
    然后是追加新的NSData
    再接下来的就是一些设置,替换等方法.........
    这里就不一一赘述了

    Demo地址:https://github.com/spicyShrimp/DEMO_OC

    相关文章

      网友评论

          本文标题:系列:iOS开发-NSNumber、NSData

          本文链接:https://www.haomeiwen.com/subject/uqeosxtx.html