我试图找出一种方法来使用typeof
来创建对self
的弱引用,以便在块中使用以避免保留周期。
当我第一次阅读此内容时,似乎惯例是使用__block typeof(self) bself = self;
,它编译但使用__block
来避免保留周期不再起作用,应使用__weak
代替。
但是__weak typeof(self) bself = self;
会导致错误:
类型'typeof(self)'(又名'TUAccountsViewController * const __strong')已经设置了保留属性
有没有办法使用typeof
或其他来电来一般性地创建对self
的弱引用?
答案 0 :(得分:37)
在最新的clang版本 Apple clang 4.0版(标签/ Apple / clang-421.1.48)(基于LLVM 3.1svn),即 Xcode 4.4 + ,不再需要__typeof__((__typeof__(self))self)
技巧。 __weak typeof(self) bself = self;
行将编译得很好。
答案 1 :(得分:32)
这有效!
__typeof__(o) __weak
我在我的BBlock项目中定义为BBlockWeakSelf
,可以像这样使用:
BBlockWeakSelf wself = self;
https://github.com/kgn/BBlock/blob/master/BBlock.h
根据Aleph7的回复进行编辑。
答案 2 :(得分:18)
正确的方法是
__weak ActualClassName* weakSelf = self;
除了在代码中添加非可移植的元语言之外,宏只会让人不清楚变量实际上是什么,以及你实际使用它的是什么。
如果您需要比ActualClassName提供的类更通用的版本,则不再处理self
,因为定义了self
,self
的类也是如此定义。
在这些情况下,您应该在继承树中使用最接近的基类名称NSObject
或更好,从不id
,例如。
__weak MyBaseClassName* weakObject = object;
答案 3 :(得分:16)
根据我的经验,要走的路是:
__typeof__(self) __weak weakSelf = self;
Note how the ownership qualifier belongs in front of the actual variable.
使用它时发生的事情非常明显,它可以在Xcode中制作成一个方便的代码片段,这使得它更容易在任何需要它的项目或类中使用。 (我使用“ws”作为代码片段的完成快捷方式)
嗯..我在这里需要一个弱引用..
ws{return}
完成。不需要在未来的项目中包含标题,只需使用该片段。
标题:Generic Weak Self Reference
平台:All
语言:Objective-C
完成快捷方式:ws
完成范围:Function or Method
代码:__typeof__(self) __weak weakSelf = self;
修改:根据comments添加了有关所有权限定符位置的备注,以及Xcode代码段
答案 4 :(得分:3)
为什么不使用
__weak id bself = self;
答案 5 :(得分:3)
我认为使用它可以:
__弱__typeof(& * self)weakSelf = self;
它引用了AFNetworking的AFURLConnectionOperation.m代码。
答案 6 :(得分:2)
我有类似的错误,但我修正了它:
我去了Project Navigator - >项目 - >目标 - >构建设置
我在那里寻找C语言方言。我把它从c11改为GNU99,它解决了我的问题。
我希望它有所帮助:)
答案 7 :(得分:1)
declareBlockSafe(self)然后在块内blk(self)。 Self可以是任何变量或实例变量。使用declareBlockSafeAs进行属性和方法返回。
如果您导入Mike Ash的精彩MAZeroingWeakRef,也适用于非ARC。 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
#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
对于ARC,你真的不需要blk(),只是为了使非宏可以以相同的方式使用宏。
答案 8 :(得分:1)
我有这个宏
#define weaken(object) __typeof__(self) __weak weakSelf = object
我像这样使用它
weaken(self);
//The block referencing weakSelf goes here
答案 9 :(得分:0)
__unsafe_unretained怎么样?这不像__weak那么安全,但这是我唯一能想到的。另外,为什么要使用typeof()?