2014-04-21 61 views
0

我使用NSProxy子類和forwardInvocation:捕獲對我的後端API對象(共享實例)的調用。NSProxy和forwardInvocation:調用塊內調用導致零返回值

一些背景信息: 我想捕獲API調用,所以我可以每次檢查是否需要刷新我的身份驗證令牌。如果是,我只是在之前執行刷新。

方法參數(invocation)包含塊。

一些簡化代碼:

- (void)forwardInvocation:(NSInvocation *)invocation { 

    [invocation setTarget:self.realAPI]; 
    [invocation retainArguments]; 

    // Perform refresh call and forward invocation after 
    // successfully refreshed 
    if (authenticationRefreshNeeded) { 

     [self.realAPI refreshWithBlock:^(NSObject *someObject) { 

      [invocation invokeWithTarget:self.realAPI]; 

     }]; 
    } 
    // Otherwise we just forward the invocation immediately 
    else { 

     [invocation invokeWithTarget:self.realAPI]; 
    } 

    return; 
} 

我已經打電話retainArguments所以我的塊和其他參數不要迷路,因爲invokeWithTarget:執行後期(refreshWithBlock:使一個異步API調用)的。

一切正常,到目前爲止 - 但是:

返回值調用的總是nilinvokeWithTarget:在刷新塊內進行。有沒有辦法保留返回值(如參數)?

任何提示?建議?


更新

作爲響應於@quellish: 的問題是,返回值是NSURLSessionDataTask類型(我用來顯示一個活動的指標),我在進行呼叫之後直接讀取。但代理不會立即轉發呼叫,所以返回值不存在 - 當然(我是盲人)。 什麼是可能的解決方法?我可以返回一個佔位符值,或者當方法被調用時我怎樣才能知道調用者,以便以後可以檢索返回值?

+0

你可以更新與你在哪裏讀取返回值的問題?當你調用getReturnValue時,你的調用本身是否爲零? – quellish

+0

是這樣。 Facepalm在晚上的其餘時間...任何提示我如何解決問題?或者有另一種方法來攔截執行另一個異步任務的API調用之前(無需在每個API方法中執行刷新檢查......) – orschaef

回答

0

要當你調用完成後執行操作,傳遞結果:

if (authenticationRefreshNeeded) { 

    [self.realAPI refreshWithBlock:^(NSObject *someObject) { 
     NSURLSessionDataTask *resultTask = nil; 
     [invocation invokeWithTarget:self.realAPI]; 
     [invocation getReturnValue:&resultTask]; 
     if (completion != nil){ 
      completion(resultTask); 
     } 
    }]; 
} 

completion()是一個塊需要一個NSURLSessionDataTask作爲參數。塊可以用作回調函數,這使得它們非常適合你想要做的事情(「當我完成了,做這個()」)理想情況下,這將被傳遞到包含上面的方法 - 但是因爲這是forwardInvocation:,這得到更多一點...具有挑戰性。您可以將其設置爲此代理對象上的屬性並從此處讀取它。

另一種方法是使用類似addDataTask:這樣的方法來擴展UIApplication類別或非正式協議,您可以調用它來代替您的塊,這會將「我剛添加數據任務」的響應性交給另一個接收器,很可能是應用程序的委託(並且可以使用新方法擴展UIApplicationDelegate協議,以處理此問題)。這聽起來像是你的數據任務和活動指標是應用程序級別的問題,這可能會使這很適合。

這就是說,我幾乎有您嘗試解決的問題(基於令牌的授權)的一些經驗。我建議考慮一下ACAccountStore如何解決這個問題,它可能會提供一些替代實現的想法。

+0

我不知道......這一切似乎都有點困難。但非常感謝您的回答。對於我所問的問題,這是正確的,即使我必須繼續尋找一個好的解決方案。 – orschaef

+0

是的,你正試圖解決的問題 - 作爲「真正」請求(用於令牌認證)的先決條件提出請求是一個令人討厭的問題。再次看看'requestAccessToAccountsWithType:options:completion''如何工作,這應該給你一些簡單而且相當可靠的方向。 – quellish

相關問題