在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

block是如何持有對象的

大?。?/span>0.3 MB 人氣: 2017-09-26 需要積分:1

  這篇文章主要會介紹 block 是如何持有并且釋放對象的。文章中的代碼都出自 Facebook 開源的用于檢測循環引用的框架 FBRetainCycleDetector。

  為什么會談到 block

  可能很多讀者會有這樣的疑問,本文既然是對 FBRetainCycleDetector 解析的文章,為什么會提到 block?原因其實很簡單,因為在 iOS 開發中大多數的循環引用都是因為 block 使用不當導致的,由于 block 會 retain 它持有的對象,這樣就很容易造成循環引用,最終導致內存泄露。

  在 FBRetainCycleDetector 中存在這樣一個類 FBObjectiveCBlock,這個類的 - allRetainedObjects 方法就會返回所有 block 持有的強引用,這也是文章需要關注的重點。

  - (NSSet *)allRetainedObjects {

  NSMutableArray *results = [[[super allRetainedObjects] allObjects] mutableCopy];

  __attribute__((objc_precise_lifetime)) id anObject = self.object;

  void *blockObjectReference = (__bridge void *)anObject;

  NSArray *allRetainedReferences = FBGetBlockStrongReferences(blockObjectReference);

  for (id object in allRetainedReferences) {

  FBObjectiveCGraphElement *element = FBWrapObjectGraphElement(self, object, self.configuration);

  if (element) {

 ?。踨esults addObject:element];

  }

  }

  return [NSSet setWithArray:results];

  }

  這部分代碼中的大部分都不重要,只是在開頭調用父類方法,在最后將獲取的對象包裝成一個系列 FBObjectiveCGraphElement,最后返回一個數組,也就是當前對象 block 持有的全部強引用了。

  Block 是什么?

  對 block 稍微有了解的人都知道,block 其實是一個結構體,其結構大概是這樣的:

  struct BlockLiteral {

  void *isa;

  int flags;

  int reserved;

  void (*invoke)(void *, 。。.);

  struct BlockDeor *deor;

  };

  struct BlockDeor {

  unsigned long int reserved;

  unsigned long int size;

  void (*copy_helper)(void *dst, void *src);

  void (*dispose_helper)(void *src);

  const char *signature;

  };

  在 BlockLiteral 結構體中有一個 isa 指針,而對 isa了解的人也都知道,這里的 isa 其實指向了一個類,每一個 block 指向的類可能是 __NSGlobalBlock__、__NSMallocBlock__ 或者 __NSStackBlock__,但是這些 block,它們繼承自一個共同的父類,也就是 NSBlock,我們可以使用下面的代碼來獲取這個類:

  static Class _BlockClass() {

  static dispatch_once_t onceToken;

  static Class blockClass;

  dispatch_once(&onceToken, ^{

  void (^testBlock)() = [^{} copy];

  blockClass = [testBlock class];

  while(class_getSuperclass(blockClass) && class_getSuperclass(blockClass) != [NSObject class]) {

  blockClass = class_getSuperclass(blockClass);

  }

 ?。踭estBlock release];

  });

  return blockClass;

  }

  Objective-C 中的三種 block __NSMallocBlock__、__NSStackBlock__ 和 __NSGlobalBlock__ 會在下面的情況下出現:

  block是如何持有對象的

  在 ARC 中,捕獲外部了變量的 block 的類會是 __NSMallocBlock__ 或者 __NSStackBlock__,如果 block 被賦值給了某個變量在這個過程中會執行 _Block_copy 將原有的 __NSStackBlock__ 變成 __NSMallocBlock__;但是如果 block 沒有被賦值給某個變量,那它的類型就是 __NSStackBlock__;沒有捕獲外部變量的 block 的類會是 __NSGlobalBlock__ 即不在堆上,也不在棧上,它類似 C 語言函數一樣會在代碼段中。

  在非 ARC 中,捕獲了外部變量的 block 的類會是 __NSStackBlock__,放置在棧上,沒有捕獲外部變量的 block 時與 ARC 環境下情況相同。

非常好我支持^.^

(1) 100%

不好我反對

(0) 0%

      發表評論

      用戶評論
      評價:好評中評差評

      發表評論,獲取積分! 請遵守相關規定!

      ?
      主站蜘蛛池模板: 日本精品视频四虎在线观看 | 美女扒开尿口让男人30视频 | 热99re久久精品2久久久 | 国产精品 视频一区 二区三区 | 黄色网在线播放 | 午夜韩国理论片在线播放 | 色拍拍综合网 | 欧美呜巴又大粗又长 | 福利视频一区二区 | 亚洲成人免费观看 | 欧美亚洲在线 | 日韩美女奶水喂男人在线观看 | 色丁香六月| 天天躁狠狠躁狠狠躁夜夜躁 | 天天躁天天狠天天透 | 理论视频在线观看 | 天天综合亚洲国产色 | 欧美成人观看免费全部完小说 | 天天操天天操天天干 | 久久精品影院永久网址 | 深爱婷婷| 色老头成人免费综合视频 | 国产gaysexchina男同men1068 | 素股中文字幕 | 国产午夜精品久久理论片小说 | www.婷婷.com| 亚洲高清视频一区 | 午夜视频色 | 中文字幕网资源站永久资源 | 美女久久久 | 亚洲色图在线播放 | 奇米久草| 久操久操 | 亚洲国产精品久久精品怡红院 | 永久在线观看视频 | 国产爱v| 日韩一级高清 | 国产乱人视频在线看 | 男女视频在线观看免费高清观看 | 日韩插插 | 久久免|