簡體   English   中英

Objective-C將一個塊傳遞到一個塊

[英]Objective-C passing a block into a block

這是一個棘手的情況。 我一直在研究塊,並且是第一次開始實現它們,而我發現自己想創建一個“復合塊”。 這大概是我的代碼:

- (void)moveToPosition:(NSInteger)pos withVelocity:(CGFloat)vel onCompletion:(void(^)(BOOL completed))completionBlock
{

    void (^compoundBlock) (BOOL completed) = ^(BOOL completed) {
        [self unlockInteractionFromPullDownMenuTab];
        void(^innerCompletionBlock)(BOOL completed) = completionBlock;
        innerCompletionBlock(completed);
    };

    // Animate
    [UIView animateWithDuration: duration
                     animations: ^void{ [self.pullDownMenu setFrame:newFrame]; }
                     completion: compoundBlock
     ];


}

目標是獲取傳遞給此方法的代碼塊,向其中添加一些內容,然后將其傳遞給動畫方法調用。 但是,我得到的訪問權限很差:

innerCompletionBlock(completed);

我認為我的innerCompletionBlock會被釋放,但是我不確定為什么。 據我了解,塊會復制您扔給它們的所有內容,包括對自我的引用,這會創建保留周期,而我最近學會了避免。

實際上,我最初嘗試過此操作:

void (^compoundBlock) (BOOL completed) = ^(BOOL completed) {
    [self unlockInteractionFromPullDownMenuTab];
    completionBlock(completed);
};

但是我遇到了錯誤的訪問,我發現也許compoundBlock並沒有復制completionBlock,所以我在塊內明確聲明了一個(block)變量,並為其分配了變量以嘗試使其保留(也許有點愚蠢,但我在ARC下運行,因此無法進行手動保留調用)。

無論如何,顯然,compoundBlock在傳遞給UIView時會被保留,但是由於我在ARC下運行,因此我不確定如何將我的onCompletion / innerCompletionBlock保留在compoundBlock中。

提前致謝 :)

啊哈,想通了。 有點愚蠢,真的。

在有些情況下我打電話的方法不同的時間- (void)moveToPosition:...並通過nilcompletionBlock參數......因為我並不需要在動畫的最后做任何額外的東西,只希望[self unlockInteractionFromPullDownMenuTab]; 這是在compoundBlock中添加的。

有道理吧?

...僅在調用該塊之前檢查是否為零。 如SO上其他地方所討論的,“執行塊時,首先測試塊是否為零很重要”。 好吧,我在那里學到了教訓。

此代碼有效:

// Compound completion block
void (^compoundBlock) (BOOL completed) = ^(BOOL completed) {
    [self unlockInteractionFromPullDownMenuTab];
    if (completionBlock != nil) {
        completionBlock(completed);
    }
};

在堆棧上創建塊。 您需要將completionBlock復制到堆中,以便可以確保在嘗試運行它時它仍然有效。 只需將其放在您的方法的頂部:

completionBlock = [completionBlock copy];

請注意,如果completionBlock 在堆上,則只會返回相同的堆副本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM