1

假设我想@synchronized(self)在一个街区内做。我想这会导致一个保留周期,所以通常我们会像这样重写它:

-(void)myMethod
{
    __weak TheClass * weakSelf = self;
    dispatch_async(dispatch_get_main_queue(),
    ^{
        TheClass * strongSelf = weakSelf;
        if(strongSelf == nil)
        {
            return;
        }

        @synchronized(strongSelf)
        {
            //mutex code
        }
    }
}

我的问题是,当您以@synchronized这种方式使用指令时,它是否等同于@synchronized(self)

4

1 回答 1

6

Short answer: No

Longer answer:

Background

For there to be a cycle involving a block the block must reference another object, and that object must (directly or via a longer chain) reference the block.

A cycle in of itself is not bad, it is only bad if it results in the lifetime of objects in the cycle being extended past the point those objects are required. It is fine to create a cycle as long as cycle is broken - by breaking one of the links forming the cycle - at some point.

A construct like:

__weak TheClass * weakSelf = self;
...
self.blockVar = ^{
    TheClass * strongSelf = weakSelf;
    ...

prevents a static cycle being created as (the object referenced by) self strongly references (the object referenced by - you get the idea, the variable isn't important but the thing being referenced by it) blockVar but blockVar only has a weak reference back to self.

However every time the block is executed it creates a strong reference (stored in strongSelf) to self and so creates a dynamic cycle - which is automatically broken when the block finishes executing.

Your code

  1. Look at your code, you create a block and pass it directly to dispatch_async - you never store a reference to the block in self. So there never is any cycle here, no need to mess with weak references at all.

  2. Once the block creates strongSelf there is a cycle, then using @synchronized(strongSelf) doesn't create a second one, it just takes a lock on the object. When the synchronized statement exits the lock goes, when the block exits the strong cycle goes.

HTH

于 2015-01-23T03:45:16.320 回答