弱自引用的通用类型

时间:2012-06-05 06:03:29

标签: objective-c cocoa automatic-ref-counting objective-c-blocks weak-references

我试图找出一种方法来使用typeof来创建对self的弱引用,以便在块中使用以避免保留周期。

当我第一次阅读此内容时,似乎惯例是使用__block typeof(self) bself = self;,它编译但使用__block来避免保留周期不再起作用,应使用__weak代替。

但是__weak typeof(self) bself = self;会导致错误:

类型'typeof(self)'(又名'TUAccountsViewController * const __strong')已经设置了保留属性

有没有办法使用typeof或其他来电来一般性地创建对self的弱引用?

10 个答案:

答案 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,因为定义了selfself的类也是如此定义。

在这些情况下,您应该在继承树中使用最接近的基类名称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}

完成。不需要在未来的项目中包含标题,只需使用该片段。


Xcode片段


标题: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()?