Generic typeof for weak self references

前端 未结 10 867
误落风尘
误落风尘 2020-12-07 11:29

I am trying to figure out a way to use typeof to create a weak reference to self for use in blocks to avoid retain cycles.

When I first rea

相关标签:
10条回答
  • 2020-12-07 12:09

    The correct way to do this is

    __weak ActualClassName* weakSelf = self;
    

    Macros only make it unclear what the variable actually is, and what you're actually doing with it, in addition to adding non-portable meta-language to your code.

    If you need a more generic version of the class than ActualClassName provides, you aren't dealing with self anymore, since where self is defined, so is the class of self defined.

    In those cases, you should use the closest base class name in your inheritance tree, NSObject or better, never id, e.g.

    __weak MyBaseClassName* weakObject = object;
    
    0 讨论(0)
  • 2020-12-07 12:10

    i think use this to be ok:

    __weak __typeof(&*self)weakSelf = self;

    it reference AFNetworking's AFURLConnectionOperation.m codes.

    0 讨论(0)
  • 2020-12-07 12:12

    why don't just use

    __weak id bself = self;
    
    0 讨论(0)
  • 2020-12-07 12:21

    What about __unsafe_unretained? That's not as safe as __weak but it's the only thing I could think of. Also, why do you use typeof()?

    0 讨论(0)
  • 2020-12-07 12:22

    declareBlockSafe( self ) then blk( self ) inside the block. Self can be any variable or instance variable. Use declareBlockSafeAs for properties and method returns.

    Also works with non-ARC if you import Mike Ash's splendid MAZeroingWeakRef. https://github.com/mikeash/MAZeroingWeakRef

    #if __has_feature(objc_arc)

    #define declareBlockSafe(__obj__) __weak typeof(__obj__) __tmpblk##__obj__ = __obj__
    #define blockSafe(__obj__) __tmpblk##__obj__
    #define blk(__obj__) blockSafe(__obj__)
    
    #define declareBlockSafeAs(__obj__, __name__) \
    __weak typeof((__obj__)) __tmpblk##__name__ = (__obj__)
    
    #else
    
    #define declareBlockSafe(__obj__) MAZeroingWeakRef *__tmpblk##__obj__ = [MAZeroingWeakRef refWithTarget:__obj__]
    #define blockSafe(__obj__) ((typeof(__obj__))__tmpblk##__obj__##.target)
    #define blk(__obj__) blockSafe(__obj__)
    
    #define declareBlockSafeAs(__obj__, __name__) \
    MAZeroingWeakRef *__tmpblk##__name__ = (__obj__)
    #endif
    

    You don't REALLY need blk() for ARC, it's just so that the macros can be used in the same way for non-ARC.

    0 讨论(0)
  • 2020-12-07 12:28

    Did you try check the C Language Dialect?

    Go to Project Navigator -> Project -> Target -> Build Settings

    There look for C Language Dialect. Change it from c11 to GNU99.

    I hope it helps :)

    0 讨论(0)
提交回复
热议问题