我在寫一個涉及事件處理的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