Generic typeof for weak self references

久未见 提交于 2019-11-28 03:09:04

In the latest clang version Apple clang version 4.0 (tags/Apple/clang-421.1.48) (based on LLVM 3.1svn), i.e. Xcode 4.4+, the __typeof__((__typeof__(self))self) trick is not necessary anymore. The __weak typeof(self) bself = self; line will compile just fine.

This works!

__typeof__(o) __weak

Which I've defined in my BBlock project as BBlockWeakSelf which can be used like this:

BBlockWeakSelf wself = self;

https://github.com/kgn/BBlock/blob/master/BBlock.h

Edited based on Aleph7's response.

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;
Thuggish Nuggets

Generic Weakself Reference (No Import Required + Snippet)


In my experience, the way to go is to use:

__typeof__(self) __weak weakSelf = self;

Note how the ownership qualifier belongs in front of the actual variable.

It's very apparent what's happening when it is used and it can be made into a handy code snippet in Xcode which makes it even easier to use in any project or class where this is needed. (I use "ws" as the snippet's completion shortcut)

Hmm.. I need a weak reference here..

ws{return}

Done. No need to ever include a header in future projects for this, just use the snippet.


Xcode Snippet


Title: Generic Weak Self Reference
Platform: All
Language: Objective-C
Completion Shortcut: ws
Completion Scopes: Function or Method
Code: __typeof__(self) __weak weakSelf = self;


Edit: Added note about ownership qualifier position based on comments, and Xcode Snippet Info

why don't just use

__weak id bself = self;

i think use this to be ok:

__weak __typeof(&*self)weakSelf = self;

it reference AFNetworking's AFURLConnectionOperation.m codes.

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 :)

SeruK

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.

I have this macro

#define weaken(object) __typeof__(self) __weak weakSelf = object

And i use it like this

weaken(self);
//The block referencing weakSelf goes here

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()?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!