Questions about get block strong layout #15

Closed
Draveness opened this Issue Jul 28, 2016 · 3 comments

Projects

None yet

3 participants

@Draveness
Draveness commented Jul 28, 2016 edited

Hi, currently I am reading source code of this lib. But some code in FBBlockStrongLayout.m really confuses me. How does this lib figure out which variable block can retain.

These lines of code are copied from _GetBlockStrongLayout function in FBBlockStrongLayout.m

  void (*dispose_helper)(void *src) = blockLiteral->descriptor->dispose_helper;
  const size_t ptrSize = sizeof(void *);

  // Figure out the number of pointers it takes to fill out the object, rounding up.
  const size_t elements = (blockLiteral->descriptor->size + ptrSize - 1) / ptrSize;

  // Create a fake object of the appropriate length.
  void *obj[elements];
  void *detectors[elements];

  for (size_t i = 0; i < elements; ++i) {
    FBBlockStrongRelationDetector *detector = [FBBlockStrongRelationDetector new];
    obj[i] = detectors[i] = detector;
  }

  @autoreleasepool {
    dispose_helper(obj);
  }

  // Run through the release detectors and add each one that got released to the object's
  // strong ivar layout.
  NSMutableIndexSet *layout = [NSMutableIndexSet indexSet];

  for (size_t i = 0; i < elements; ++i) {
    FBBlockStrongRelationDetector *detector = (FBBlockStrongRelationDetector *)(detectors[i]);
    if (detector.isStrong) {
      [layout addIndex:i];
    }

    // Destroy detectors
    [detector trueRelease];
  }

I'm quite confused about the dispose_helper here. Does the dispose_helper dealloc the objects that block retains according to their memory address? So we can fake an array of objects and use dispose_helper to dealloc our objects, and then we can find out which object of the array is not existed. So we can get indexed and retrieve all the objects which block has retained.

Thanks for your reading, and I really wanna know how this lib works. 😄

@kastiglione
Member

Does the dispose_helper dealloc the objects that block retains according to their memory address?

Yes

So we can fake an array of objects and use dispose_helper to dealloc our objects, and then we can find out which object of the array is not existed. So we can get indexed and retrieve all the objects which block has retained.

Yup

cc @Gricha

@Gricha
Contributor
Gricha commented Aug 3, 2016

Hey! Sorry for late reply.

Yeah it's exactly like that - we are faking objects that would otherwise be captured by block and we try to figure out which one the block will hold strongly. The way we do it is by using dispose helper which will take care of sending release message to objects it captured strongly.

Please let us know if you have any more questions.
Thanks!

@Gricha Gricha closed this Aug 3, 2016
@Draveness

Thanks for ur response, that helps a lot 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment