3 回答
TA貢獻1770條經(jīng)驗 獲得超3個贊
嚴格來說,它是一個const副本的事實與這個問題無關(guān)。塊將保留創(chuàng)建時捕獲的任何obj-c值。恰好,const-copy問題的解決方法與保留問題的解決方法相同; 即,使用__block變量的存儲類。
無論如何,要回答你的問題,這里沒有真正的選擇。如果你正在設(shè)計自己的基于塊的API,并且這樣做是有意義的,你可以讓塊self作為參數(shù)傳遞in 的值。不幸的是,這對大多數(shù)API來說沒有意義。
請注意,引用ivar具有完全相同的問題。如果您需要在塊中引用ivar,請使用屬性或使用bself->ivar。
附錄:編譯為ARC時,__block不再中斷保留周期。如果您正在為ARC編譯,則需要使用__weak或__unsafe_unretained替代。
TA貢獻1847條經(jīng)驗 獲得超11個贊
這可能是顯而易見的,但是self當你知道你會得到一個保留周期時,你只需要做丑陋的別名。如果塊只是一次性的東西,那么我認為你可以安全地忽略保留self。例如,當您將塊作為回調(diào)接口時,不好的情況就是如此。像這兒:
typedef void (^BufferCallback)(FullBuffer* buffer);@interface AudioProcessor : NSObject {…}@property(copy) BufferCallback bufferHandler;@end@implementation AudioProcessor- (id) init {
…
[self setBufferCallback:^(FullBuffer* buffer) {
[self whatever];
}];
…}這里的API沒有多大意義,但是在與超類通信時也是有意義的。我們保留緩沖區(qū)處理程序,緩沖區(qū)處理程序保留了我們。比較這樣的事情:
typedef void (^Callback)(void);@interface VideoEncoder : NSObject {…}- (void) encodeVideoAndCall: (Callback) block;@end@interface Foo : NSObject {…}@property(retain) VideoEncoder *encoder;@end@implementation Foo- (void) somewhere {
[encoder encodeVideoAndCall:^{
[self doSomething];
}];}在這些情況下,我不做self別名。你確實得到一個保留周期,但是操作是短暫的,并且塊最終會從內(nèi)存中斷開,從而打破周期。但是我對塊的體驗非常小self,從長遠來看,混疊可能是最佳實踐。
- 3 回答
- 0 關(guān)注
- 599 瀏覽
添加回答
舉報
