34

我试图找出一种方法来typeof创建self用于块的弱引用以避免保留周期。

当我第一次读到这个时,似乎约定是使用__block typeof(self) bself = self;,它编译但使用__block以避免保留循环不再起作用,__weak应该改用。

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

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

有没有办法使用typeof或另一个调用来一般地创建一个弱引用self

4

10 回答 10

37

在最新的 clang 版本Apple clang 版本 4.0 (tags/Apple/clang-421.1.48) (基于 LLVM 3.1svn),即Xcode 4.4+__typeof__((__typeof__(self))self)中,不再需要这个技巧了。该__weak typeof(self) bself = self;行将编译得很好。

于 2012-06-27T12:59:09.997 回答
32

这行得通!

__typeof__(o) __weak

我在我的 BBlock 项目中定义的BBlockWeakSelf可以像这样使用:

BBlockWeakSelf wself = self;

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

根据 Aleph7 的回复进行编辑。

于 2012-06-06T19:53:43.943 回答
18

正确的方法是

__weak ActualClassName* weakSelf = self;

除了在代码中添加不可移植的元语言之外,宏只会让人不清楚变量实际上是什么,以及您实际上在用它做什么。

如果你需要一个比 ActualClassName 提供的更通用的类版本,你就不用再处理self了,因为定义了 where self,所以定义了类self

在这些情况下,您应该在继承树中使用最接近的基类名称,NSObject或者更好的是 never id,例如

__weak MyBaseClassName* weakObject = object;
于 2013-02-12T15:17:21.680 回答
16

通用弱自身参考(无需导入 + 片段)


以我的经验,要走的路是使用:

__typeof__(self) __weak weakSelf = self;

请注意所有权限定符如何位于实际变量的前面。

使用它时发生的事情非常明显,并且可以在 Xcode 中制作成一个方便的代码片段,这使得在任何需要它的项目或类中使用它变得更加容易。(我使用“ws”作为片段的完成快捷方式)

嗯..我在这里需要一个弱参考..

ws{return}

完毕。无需为此在未来的项目中包含标题,只需使用代码段即可。


Xcode 片段


标题:Generic Weak Self Reference
平台:All
语言:Objective-C
完成快捷方式:ws
完成范围:Function or Method
代码:__typeof__(self) __weak weakSelf = self;


编辑:添加了关于基于评论的所有权限定符位置的注释,以及 Xcode Snippet Info

于 2013-10-03T20:20:43.640 回答
3

为什么不直接使用

__weak id bself = self;
于 2012-06-05T06:07:21.720 回答
3

我认为使用它就可以了:

__weak __typeof(&*self)weakSelf = self;

它引用了 AFNetworking 的 AFURLConnectionOperation.m 代码。

于 2013-01-22T16:51:22.900 回答
2

您是否尝试检查 C 语言方言?

转到项目导航器 -> 项目 -> 目标 -> 构建设置

那里寻找 C 语言方言。将其从 c11 更改为 GNU99。

我希望它有帮助:)

于 2015-12-11T17:53:19.113 回答
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

对于 ARC,您真的不需要 blk(),只是这样宏可以以与非 ARC 相同的方式使用。

于 2013-04-26T21:24:25.633 回答
1

我有这个宏

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

我像这样使用它

weaken(self);
//The block referencing weakSelf goes here
于 2014-05-12T09:20:06.417 回答
0

__unsafe_unretained 呢?这不如 __weak 安全,但这是我唯一能想到的。另外,为什么要使用 typeof()?

于 2012-06-05T10:56:35.197 回答