我在写一个涉及事件处理的API,我希望能够为处理程序使用块。回调通常需要访问或修改自我。在ARC模式中,Clang警告说,引用自我的块可能会创建一个保留周期,这似乎是我希望保持一般的有用警告。紧凑地禁用自引用块的弧保留周期警告
但是,对于我的API的这一部分,回调的生命周期和包含对象在外部维护。我知道当对象被释放时我可以打破这个循环。
我可以使用#pragma clang diagnostic ignored "-Warc-retain-cycles"
关闭每个文件的保留周期警告,但会禁用整个文件的警告。围绕这个警告,我可以用#pragma clang diagnostic push
和pop
围绕这些块,但是这会使块变得丑陋。
我也可以通过引用指向self的__weak变量而不是直接引用self来得到警告,但这会使得块的使用更加不愉快。
我想出了最好的解决方案是这个宏,做各地块的诊断停用:
#define OBSERVE(OBJ, OBSERVEE, PATH, CODE) \
[(OBJ) observeObject:(OBSERVEE) forKeyPath:(PATH) withBlock:^(id obj, NSDictionary *change) { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-retain-cycles\"") \
do { CODE; } while(0); \
_Pragma("clang diagnostic pop") \
}];
这样的作品,但它不是API的用户很发现的,它不允许嵌套观察员,它与XCode的编辑器交互不佳。有没有更好的方法来禁用或避免警告?
创建'self'的__weak引用实际上需要一行代码。我认为在这种情况下解决问题要比试图缓解症状好。如何引用'weakSelf'而不是'self'使得块的使用更愉快? –
它在一些方面不太愉快。听众往往很短,有时只是一个声明。 __weak声明使侦听器的大小加倍。这也意味着你需要限定财产访问而不是使用推断自我。我会同意我目前的解决方案可能比只使用__weak更糟糕,但我希望通过这个问题获得更好的解决方案。 –
你可以改变你的完成块的原型来接受一个“自我”的论点吗?现在你传递块的代码看起来是一样的(除了接受一个额外的参数),你可以消除警告。 (即让您的API将相关对象传递给您的块) – nielsbot