Objective c 除了弱/强舞蹈之外,在块中使用实例变量还有其他方法吗?

Objective c 除了弱/强舞蹈之外,在块中使用实例变量还有其他方法吗?,objective-c,objective-c-blocks,instance-variables,weak-references,Objective C,Objective C Blocks,Instance Variables,Weak References,在Objective-C中,您可能希望在块内使用实例变量,并将该块存储在对象本身中。如果这样做,那么要确保不创建循环依赖项,并使所有编译器警告静音,您将遇到相当大的麻烦: @implementation TestBlock { int someVariable; void (^someBlock)(); } - (void) createBlock { // ideally I would like to use: someBlock = ^{

在Objective-C中,您可能希望在块内使用实例变量,并将该块存储在对象本身中。如果这样做,那么要确保不创建循环依赖项,并使所有编译器警告静音,您将遇到相当大的麻烦:

@implementation TestBlock {
    int someVariable;
    void (^someBlock)();
}

- (void) createBlock
{
    // ideally I would like to use:
    someBlock = ^{
        someVariable++;
    };

    // but in reality I need to use:
    TestBlock * __weak weakSelf = self;
    someBlock = ^{
        TestBlock *strongSelf = weakSelf;
        strongSelf->someVariable++;
    };
}

@end
如果使用的是
weakSelf
,而不是
strongSelf
,则会出现以下错误:

不允许取消对弱指针的引用

如果直接使用
self
,则会创建一个保留周期


我知道为什么需要这样做的背景,但是在块中使用实例变量真的没有更简单的方法吗?您是否使用过任何实用的方法使其更简短、更可读?

如果您为ivar创建了
属性
,您可以直接在
引用上引用该属性(尽管它实际上是一个方法调用)。如果您想直接访问实例变量,那么您必须执行发布代码中的
/
舞蹈


我意识到这是一个Objective-C问题,但值得注意的是,这是Swift解决的问题。

您没有其他选项可以直接访问ivar。但是您可以选择使用ivar周围的属性。然后可以使用
wealSelf
访问属性。如果必须访问ivar,可以使用“@weakify”和“@strongify”宏,这使其可读性更强。关键是避免将块作为ivar。例如,您可以重新设计类,使其具有接受块作为参数的方法。@Reinhard Männer我不知道您提到的weakify strongify宏,这是一个有趣的想法,我一定会尝试。至少它使事情变得简洁明了。@CouchDeveloper像我在示例中所展示的那样,将块作为直接实例变量确实很少见。但是,iVar中包含另一个类的对象是非常常见的,该对象包含您提供给它的块。当然,当您只想增加一个int时,属性访问是一件非常麻烦的事情:
[self-setSomeVariable:[self-someVariable]+1]写入
self.someVariable=self.someVariable+1是有效的Objective-C属性语法
self.someVariable++
甚至是有效的语法。但就问题的前提而言,直接创建ivar是一个好主意是非常罕见的。使用
->
访问它是一个好主意,这一点更不常见。属性是实现所有这些的正确方法。(虽然属性在大多数情况下仍然需要一些强/弱的舞蹈。正如CouchDeveloper所建议的,如果可能的话,最好尝试围绕需要它进行设计。)这是事实,这当然是最好的方法。有些地方你别无选择,只能跳
strong
/
weak
舞蹈(比如
NSNotificationCenter
基于块的API)。将其作为一个属性将把问题减少一半(你仍然需要它的薄弱部分)。但我真的不喜欢出于纯粹的技术原因使用属性,就像这样。属性对于类的公共变量非常有用,但是对于它的私有数据,我看不出使用它们的真正概念上的原因。因此,我觉得使用IVAR更清晰、更直接、更高效。