iOS NSValue 和 @encode 詳解

一、NSValue 很有用的包裝對象的兩個用法

    NSData*data = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:@"www.baidu.com"]];
    /** 用 NSValue 包裝 Objective-C 對象 */
    NSValue *value = [NSValue valueWithBytes:&data objCType:@encode(NSString)];
    NSLog(@"%@",value);
    /** NSValue 創建並返還一個包含給定對象的  */
    NSObject*objc = [NSObject new];
    NSValue * value2 = [NSValue valueWithNonretainedObject:objc];
    NSLog(@"%@",value2);

二、關於 @encode

  • 意義:@編譯器指令 之一,返回一個給定類型編碼爲一種內部表示的字符串(例如,@encode(int) → i),類似於 ANSI C 的 typeof 操作。蘋果的 Objective-C 運行時庫(runtime)內部利用類型編碼幫助加快消息分發。

                               Objective-C Type Encodings

    編碼 意義
    c ---> A char
    i ---> An int
    s ---> A short
    l ---> A longl is treated as a 32-bit quantity on 64-bit programs.
    q ---> A long long
    C ---> An unsigned char
    I ---> An unsigned int
    S ---> An unsigned short
    L ---> An unsigned long
    Q ---> An unsigned long long
    f ---> A float
    d ---> A double
    B ---> A C++ bool or a C99 _Bool
    v ---> A void
    " ---> A character string (char )(最前方的”是爲了格式才添加)
    @ ---> An object (whether statically typed or typed id)
    "# ---> A class object (Class)(最前方的“是爲了格式才添加)
    : ---> A method selector (SEL)
    [array type] ---> An array
    {name=type...} ---> A structure
    (name=type...) ---> A union
    bnum ---> A bit field of num bits
    ^type ---> A pointer to type
    ? ---> An unknown type (among other things, this code is used for function pointers)

  • 我們也可以嘗試去打印這些值

      NSLog(@"int        : %s", @encode(int));
      NSLog(@"float      : %s", @encode(float));
      NSLog(@"float *    : %s", @encode(float*));
      NSLog(@"char       : %s", @encode(char));
      NSLog(@"char *     : %s", @encode(char *));
      NSLog(@"BOOL       : %s", @encode(BOOL));
      NSLog(@"void       : %s", @encode(void));
      NSLog(@"void *     : %s", @encode(void *));
    
      NSLog(@"NSObject * : %s", @encode(NSObject *));
      NSLog(@"NSObject   : %s", @encode(NSObject));
      NSLog(@"[NSObject] : %s", @encode(typeof([NSObject class])));
      NSLog(@"NSError ** : %s", @encode(typeof(NSError **)));
    
      int intArray[5] = {1, 2, 3, 4, 5};
      NSLog(@"int[]      : %s", @encode(typeof(intArray)));
    
      float floatArray[3] = {0.1f, 0.2f, 0.3f};
      NSLog(@"float[]    : %s", @encode(typeof(floatArray)));
    
      typedef struct _struct {
          short a;
          long long b;
          unsigned long long c;
      } Struct;
      NSLog(@"struct     : %s", @encode(typeof(Struct)));
  • Method Ecoding

    MethodEcoding.png
  • 這裏有需要注意的是:
    • 指針的標準編碼是加一個前置的 ^,而 char 擁有自己的編碼 。這在概念上是很好理解的,因爲 C 的字符串被認爲是一個實體,而不是指針。
    • BOOL 是 c,而不是某些人以爲的 i。原因是 char 比 int 小,且在 80 年代 Objective-C 最開始設計的時候,每一個 bit 位都比今天的要值錢(就像美元一樣)。BOOL 更確切地說是 signed char (即使設置了 -funsigned-char 參數),以在不同編譯器之間保持一致,因爲 char 可以是 signed 或者 unsigned。
    • 直接傳入 NSObject 將產生 #。但是傳入 [NSObject class] 產生一個名爲 NSObject 只有一個類字段的結構體。很明顯,那就是 isa 字段,所有的 NSObject 實例都用它來表示自己的類型。
發佈了60 篇原創文章 · 獲贊 17 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章