色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

您好,歡迎來電子發燒友網! ,新用戶?[免費注冊]

您的位置:電子發燒友網>源碼下載>通訊/手機編程>

objc源碼中NSObject如何進行初始化

大小:0.2 MB 人氣:0 2017-09-26 需要積分:1

  + alloc 和 - init 這一對我們在 iOS 開發中每天都要用到的初始化方法一直困擾著我, 于是筆者仔細研究了一下 objc 源碼中 NSObject 如何進行初始化。

  在具體分析對象的初始化過程之前,我想先放出結論,以免文章中的細枝末節對讀者的理解有所影響;整個對象的初始化過程其實只是 為一個分配內存空間,并且初始化 isa_t 結構體的過程。

  alloc 方法分析

  先來看一下 + alloc 方法的調用棧(在調用棧中省略了很多不必要的方法的調用):

  id _objc_rootAlloc(Class cls)

  └── static id callAlloc(Class cls, bool checkNil, bool allocWithZone=false)

  └── id class_createInstance(Class cls, size_t extraBytes)

  └── id _class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, bool cxxConstruct, size_t *outAllocatedSize)

  ├── size_t instanceSize(size_t extraBytes)

  ├── void *calloc(size_t, size_t) └── inline void objc_object::initInstanceIsa(Class cls, bool hasCxxDtor)

  這個調用棧中的方法涉及了多個文件中的代碼,在下面的章節中會對調用的方法逐步進行分析,如果這個調用棧讓你覺得很頭疼,也不是什么問題。

  alloc 的實現

  + (id)alloc {

  return _objc_rootAlloc(self);

  }

  alloc 方法的實現真的是非常的簡單, 它直接調用了另一個私有方法 id _objc_rootAlloc(Class cls)

  id _objc_rootAlloc(Class cls) {

  return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);

  }

  這就是上帝類 NSObject 對 callAlloc 的實現,我們省略了非常多的代碼,展示了最常見的執行路徑:

  static id callAlloc(Class cls, bool checkNil, bool allocWithZone=false) {

  id obj = class_createInstance(cls, 0);

  return obj;

  }

  id class_createInstance(Class cls, size_t extraBytes) {

  return _class_createInstanceFromZone(cls, extraBytes, nil);

  }

  對象初始化中最重要的操作都在 _class_createInstanceFromZone 方法中執行:

  static id _class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, bool cxxConstruct = true, size_t *outAllocatedSize = nil) {

  size_t size = cls-》instanceSize(extraBytes);

  id obj = (id)calloc(1, size);

  if (!obj) return nil;

  obj-》initInstanceIsa(cls, hasCxxDtor);

  return obj;

  }

  對象的大小

  在使用 calloc 為對象分配一塊內存空間之前,我們要先獲取對象在內存的大小:

  size_t instanceSize(size_t extraBytes) {

  size_t size = alignedInstanceSize() + extraBytes;

  if (size 《 16) size = 16;

  return size;

  }

  uint32_t alignedInstanceSize() {

  return word_align(unalignedInstanceSize());

  }

  uint32_t unalignedInstanceSize() {

  assert(isRealized());

  return data()-》ro-》instanceSize;

  }

  實例大小 instanceSize 會存儲在類的 isa_t 結構體中,然后經過對齊最后返回。

  Core Foundation 需要所有的對象的大小都必須大于或等于 16 字節。

  在獲取對象大小之后,直接調用 calloc 函數就可以為對象分配內存空間了。

  isa 的初始化

  在對象的初始化過程中除了使用 calloc 來分配內存之外,還需要根據類初始化 isa_t 結構體:

  inline void objc_object::initIsa(Class cls, bool indexed, bool hasCxxDtor) {

  if (!indexed) {

  isa.cls = cls;

  } else {

  isa.bits = ISA_MAGIC_VALUE;

  isa.has_cxx_dtor = hasCxxDtor;

  isa.shiftcls = (uintptr_t)cls 》》 3;

  }

  }

  上面的代碼只是對 isa_t 結構體進行初始化而已:

  union isa_t { isa_t() { }

  isa_t(uintptr_t value) : bits(value) { }

  Class cls;

  uintptr_t bits;

  struct {

  uintptr_t indexed : 1;

  uintptr_t has_assoc : 1;

  uintptr_t has_cxx_dtor : 1;

  uintptr_t shiftcls : 44;

  uintptr_t magic : 6;

  uintptr_t weakly_referenced : 1;

  uintptr_t deallocating : 1;

  uintptr_t has_sidetable_rc : 1;

  uintptr_t extra_rc : 8;

  };

  };

  init 方法

  NSObject 的 - init 方法只是調用了 _objc_rootInit 并返回了當前對象:

  - (id)init {

  return _objc_rootInit(self);

  }

  id _objc_rootInit(id obj) {

  return obj;

  }

非常好我支持^.^

(0) 0%

不好我反對

(0) 0%

用戶評論

      ?
      主站蜘蛛池模板: 强奷漂亮女老板在线播放 | 肉肉描写很细致的黄文 | jizz教师 | 99re8热视频这在线视频 | 亚洲天堂999| A级毛片无码久久精品免费 a级毛片黄免费a级毛片 | 成人天堂资源WWW在线 | 琪琪午夜福利免费院 | 国产在线观看99 | 国产在线精品亚洲观看不卡欧美 | 特黄大片aaaaa毛片 | 亚洲黄色高清视频 | 国产麻豆精品久久一二三 | 国产精品视频免费视频 | 性夜a爽黄爽 | 欧美亚洲国产手机在线有码 | 伊人久久99热这里只有精品 | 国产精品无码视频一区二区 | 蜜桃成熟时33D在线嘟嘟网 | 一边吃奶一边啪啪真舒服 | 国产午夜精品美女免费大片 | 乳液全集电影在线观看 | 日本午夜精品理论片A级APP发布 | yw193.c国产在线观看 | 无限资源好看片2019免费观看 | 国产1769一七六九视频在线 | xxx88中国| 精品无码人妻一区二区免费AV | 久久视频在线视频观看天天看视频 | 尤物久久99国产综合精品 | 国产精品1卡二卡三卡四卡乱码 | 24小时日本在线观看片免费 | 国产国拍亚洲精品av麻豆 | 天天爽夜夜爽8888视频精品 | 超碰免费视频在线观看 | 好男人好资源在线观看免费视频 | 陈红下面又紧又小好爽 | 调教玩弄奶头乳夹开乳震动器 | 九九久久精品 | 国产一区二区三区四区五在线观看 | 久久精品热老司机 |