<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      iOS 反射 學習 和 運用

      iOS  反射 學習 和 運用

      反射:  通過 類名來獲得生成的相應的類的實例 的這種機制  叫 反射

      常用的反射方式

      1. 把 NSDictionary  轉成 自定義 model
      2. 自定義 model 轉成  NSDictionary

      (1)第一種 其實很好實現的 ,你可以自己寫映射關系 對應 ,也可以使用一些優秀的第三方,比如 MJExtension 等  特別方便

      (2)MJExtension 有一個方法  valueKey,  這個 是可以轉字典

      但是這種方法是有局限的  當這個 比較適合 單層次的model類  不適合 自己子類 有自定義model 或者 自己本身是繼承于其他自定義model的派生類

      因為很多時候我想轉成字典  我是想把它通過字典轉json 做緩存 ,如果 這個字典 中有自定義類 (另外 如果有UI類型的類 比如 UIColor  UIView UILabel 等非數據級別的) 會在轉成json的過程中因不被識別導致失敗 而崩潰.

      在網上查了 好多資料  有很多類似的說法

      ”對象的類,如果是派生類,就得靠其他方式來實現了,因為得到不該基類的屬性”  (錯誤的一句話,上網 搜去 一大堆)

      看到 各種轉載 之后 甚至 自己都怯步了 靠 我能做到嗎?

      現在我可以說  能啊 用腳想 實際運用的時候 不就是通過點語法獲取 父類/子類的屬性 或者方法的么  反過來 為啥不行 ?

      Java C# 反射很常見   iOS也一定行!!!

      關鍵代碼來了

      先上幾個要點

      反射 動用了 底層 主要是 c 語言

      (1)頭文件  #import <objc/runtime.h>

      (2) 算法策略 DFS  

      (3)  通過調用自身的class方法獲取當前類的元數據信息

           通過runtime的 class_copyPropertyList 方法取得當前類的屬性列表,以指針數組的形  式返  回

           遍歷指針數組,通過property_getName獲取屬性名,property_getAttributes獲取屬性類型

      (4)判斷條件 

        a.  用[value class]得到的都是 JKArray JKdictionary  __NSCFString __NSCFConstantString 等 類簇級別的  他們的父類的父類 或者說 他們 是 NSString  等 的一個小子類,判斷冗余條件太多 不容易窮盡 也不夠科學  所以 獲取類 必須用 property_getAttributes來取 才能取到 NSString NSArray 等 NS級別的 

      轉化后 是一個字符串 類型的類 

      再轉換成類 方法是:

      Class propertyClass = NSClassFromString(className); 

      這種方法優勢是動態獲取 甚至不用 添加 頭文件 來制約 甚是方便,因為 類 在搜索過程中 他本來就是從物理條件 匿名 出發  你不可能提前角度 知道 你將要搜索到什么類

      b. 關鍵就是 節點檢索條件

       我設計的是  

      向下:如果當前節點 是一個 系統級別的類 那么它已經是葉子節點   否則 需要進一步DFS

      向上:DFS  當前類的 superClass  

      結束條件: class 為空 或者 已經到 基類 NSObject 

      判斷 是否 是系統級別的類方法

      if (propertyClass == NULL) {
      
      } else {
      
          NSBundle *mainB = [NSBundle bundleForClass:propertyClass];
          if (mainB == [NSBundle mainBundle]) {
              DLog(@"自定義的類");
          } else {
                 DLog(@"系統的類");
      //        if (propertyClass == [UIColor class]) { //看需求 處理
      //            continue;
      //        }
          }
      }

       原理:就是看這個類 是不是在沙盒里 在  肯定是系統級別的,否則 是 自定義的

      上代碼:

      //
      //  NSDictionary+ModelConvert.h
      //  dailylife
      //
      //  Created by HF on 16/3/9.
      //
      //
      
      #import <Foundation/Foundation.h>
      
      @interface NSDictionary (ModelConvert)
      
      /**
       * 拓展  獲得當前類 及 子類 和 父類 的全部 屬性和屬性值
       * get current object as well as the properties inherited from the parent classes
       * @returns (NSString) Dictionary of property name --> value
       *
       * 注意 不應該 使用 UI 的類 做處理 可以生成字典  但是轉json會崩潰  
       */
      + (NSDictionary *)toDictionaryFromModel:(id)objectModel;
      
      @end
      //
      //  NSDictionary+ModelConvert.m
      //  dailylife
      //
      //  Created by HF on 16/3/9.
      //
      //
      
      #import "NSDictionary+ModelConvert.h"
      #import <objc/runtime.h>
      
      @implementation NSDictionary (ModelConvert)
      
      + (NSDictionary *)toDictionaryFromModel:(id)objectModel{
          return [NSDictionary classPropsForClassHierarchyObjectModel:objectModel
                                                                class:[objectModel class] onDictionary:[NSMutableDictionary dictionary]];
      }
      
      static const char *getPropertyType(objc_property_t property) {
          const char *attributes = property_getAttributes(property);
          //printf("attributes=%s\n", attributes);
          char buffer[1 + strlen(attributes)];
          strcpy(buffer, attributes);
          char *state = buffer, *attribute;
          while ((attribute = strsep(&state, ",")) != NULL) {
              if (attribute[0] == 'T' && attribute[1] != '@') {
                  // it's a C primitive type:
                  
                  // if you want a list of what will be returned for these primitives, search online for
                  // "objective-c" "Property Attribute Description Examples"
                  // apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc.
                  
                  NSString *name = [[NSString alloc] initWithBytes:attribute + 1 length:strlen(attribute) - 1 encoding:NSASCIIStringEncoding];
                  return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
              }
              else if (attribute[0] == 'T' && attribute[1] == '@' && strlen(attribute) == 2) {
                  // it's an ObjC id type:
                  return "id";
              }
              else if (attribute[0] == 'T' && attribute[1] == '@') {
                  // it's another ObjC object type:
                  NSString *name = [[NSString alloc] initWithBytes:attribute + 3 length:strlen(attribute) - 4 encoding:NSASCIIStringEncoding];
                  return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
              }
          }
          return "";
      }
      
      + (NSDictionary *)classPropsForClassHierarchyObjectModel:(id)objectModel class:(Class)klass onDictionary:(NSMutableDictionary *)results
      {
          if (klass == NULL) {
              return nil;
          }
      
          //stop if we reach the NSObject class as is the base class
          if (klass == [NSObject class]) {
              return [NSDictionary dictionaryWithDictionary:results];
          }
          else{
              unsigned int outCount, i;
              objc_property_t *properties = class_copyPropertyList(klass, &outCount);
              if (outCount == 0) {
                  free(properties);
                  return nil;
              }
              
              for (i = 0; i < outCount; i++) {
                  objc_property_t property = properties[i];
                  const char *propName = property_getName(property);
                  if(propName) {
                      NSString *propertyName = [NSString stringWithUTF8String:propName];
                      id value = [objectModel valueForKey:propertyName];
                      if (value) {
                          const char *propType = getPropertyType(property);
                          NSString *className = [NSString stringWithCString:propType
                                                                   encoding:[NSString defaultCStringEncoding]];
                          Class propertyClass = NSClassFromString(className);
                          DLog(@"%@ == %@",className,NSClassFromString(className));
       
                          if (propertyClass == NULL) {
                              [results setObject:value forKey:propertyName];
                          } else {
                              
                              DLog(@"%@",propertyName);
                              DLog(@"%@",value);
                              DLog(@"%@",[value class]);
                              NSBundle *mainB = [NSBundle bundleForClass:propertyClass];
                              if (mainB == [NSBundle mainBundle]) {
                                  DLog(@"自定義的類");
                                  NSDictionary *dic = [NSDictionary toDictionaryFromModel:value]; //向下處理
                                  [results setObject:dic  forKey:propertyName];
                              } else {
                                  DLog(@"系統的類");
                                  if (propertyClass == [UIColor class]) {//看需求處理
                                      continue;
                                  }
                                  [results setObject:value forKey:propertyName];
                              }
                          }
                      }
                  }
              }
              free(properties);
              //go for the superclass
              return [NSDictionary classPropsForClassHierarchyObjectModel:objectModel  class:[klass superclass] onDictionary:results];//向上處理
          }
      }
      
      @end

       

       參考 多重繼承類

      1.

       

      2.

      3.

       

      使用:

      運行打印

      ShowDataFeedModel 還有個屬性 是屬性 是 foodTags  這里沒打印 出來 是因為 value是空的  我沒有 把 value為空的對象 放在 字典集合中 如果 需要的話 可以處理的  放進空數據就好了

      這樣的字典集合 可以直接轉換成 json 存儲  需要的 時候 再轉換成 對應的 數據model  妥妥的

       

      好的學習方法很重要, 拆第三方包 看究竟也不錯 沒準 能給自己一些啟發

      最重要的是 敢于實踐和探究  有人說 不能實現 不一定吧  寫完這篇博文 我能開心好幾天

      參考:

      http://blog.csdn.net/yongyinmg/article/details/39890423 (從JSONModel看Objective-C的反射機制 )

       

      posted on 2016-04-19 14:24  ACM_Someone like you  閱讀(951)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 国产口爆吞精在线视频2020版| 亚洲 欧洲 自拍 偷拍 首页 | 国产成人亚洲欧美二区综合| 97精品伊人久久久大香线蕉| 国产精品一久久香蕉产线看| 91中文字幕一区二区| 欧洲码亚洲码的区别入口| 國产AV天堂| 午夜福利理论片高清在线| 国产精品国语对白一区二区 | 动漫精品中文无码卡通动漫| 丁香五月婷激情综合第九色| 久久不见久久见免费影院www日本| av色国产色拍| 亚洲一品道一区二区三区| 亚洲国产亚洲综合在线尤物| JIZZJIZZ国产| 中文字幕结果国产精品| 国产精品久久久久久久久软件| 午夜视频免费试看| 老色批国产在线观看精品| 亚洲欧美综合一区二区三区| 蜜桃亚洲一区二区三区四| 深田えいみ禁欲后被隔壁人妻| 精品久久国产字幕高潮| 精品午夜福利无人区乱码| 欧美日韩精品一区二区视频| 秋霞无码一区二区| 无码AV中文字幕久久专区| 最近中文字幕mv免费视频| 少妇又爽又刺激视频| 成人自拍小视频免费观看| 国产精品国产三级国产试看| 乱中年女人伦av二区| 国产jlzzjlzz视频免费看 | 日本免费一区二区三区日本| 久久三级中文欧大战字幕| 777米奇影视第四色| 亚洲av永久无码精品网站| 国产偷窥熟女高潮精品视频| 欧美成本人视频免费播放|