2013-04-25 72 views
1

大家好, 我一直在研究Objective-C中的一些枚舉例程來執行對象反思。特別是,我正在快速列舉NSSet,並在調整其屬性和/或調用其方法之前,確保其中的對象屬於類BBBallView(我非常不幸)。爲了使解析器和編譯器很開心,然而,我最終將對象轉換爲每一行上的類;此外,爲了訪問它的屬性,對象的轉換必須放在括號內,否則點符號將不起作用。這導致有些凌亂代碼:Obj-C反思:如何避免所有時間投射?

for (id otherBall in self.gameField.subviews) { 
    if ([otherBall isKindOfClass:[BBBallView class]]) { 
     if (!((BBBallView *)otherBall).isEnlarged) { 
      CGRect otherFrame = ((BBBallView *)otherBall).frame; 
      /* ... */ 
     } 
    } 
} 

有沒有辦法告訴編譯器像「在這一點上我知道otherBallBBBallView,所以別再告訴我,它不會對這些選擇和響應特性「?這樣,可以只寫:

for (id otherBall in self.gameField.subviews) { 
    if ([otherBall isKindOfClass:[BBBallView class]]) { 
     if (!otherBall.isEnlarged) { 
      CGRect otherFrame = otherBall.frame; 
      /* ... */ 
     } 
    } 
} 

等等。

我試過otherBall = (BBBallView *)otherBall但是「快速枚舉變量不能在默認情況下在ARC中修改」。將枚舉變量更改爲__strong id可以修復它,但不會幫助任何後續行發出錯誤,例如在'const __strong id'類型的對象上找不到屬性isEnlarged「,所以我又回到了原點。

我甚至不確定爲什麼會發生這種情況:當變量是id類型的變量時,編譯器是否應該避開它?無論如何,對於需要對物體屬性進行多次計算的方法而言,整個磨難尤其麻煩,因爲它在所有括號中很快就變得無法讀取。

有沒有辦法解決這個問題?

在此先感謝!

+0

一般來說,內省繁重模式是*代碼氣味*。集合通常不應該包含異類。此外,擁有一個抽象類,提供基本服務和特定的子類,可以改進行爲,避免了大量的內省。 – bbum 2013-04-25 17:01:50

回答

4

您可以使用正確的類型創建本地臨時文件,也可以不使用點符號。

  1. 本地臨時

    for (UIView *view in self.gameField.subviews) { 
        if ([view isKindOfClass:[BBBallView class]]) { 
        BBBallView *ballView = view; 
        if (!ballView.isEnlarged) { 
         CGRect otherFrame = ballView.frame; 
         /* ... */ 
        } 
        } 
    } 
    
  2. 不要用點號

    for (id otherBall in self.gameField.subviews) { 
        if ([otherBall isKindOfClass:[BBBallView class]]) { 
        if (![otherBall isEnlarged]) { 
         CGRect otherFrame = [otherBall frame]; 
         /* ... */ 
        } 
        } 
    } 
    

如果我只是做了幾件事情我會被誘惑不使用點符號。如果閱讀變得很尷尬,並且有很多訪問,那麼我會考慮本地臨時文件

+1

我只是想寫出完全相同的答案......但你打賭我! +1 :) – HAS 2013-04-25 14:10:47

+0

你有一點(沒有雙關語!),使用臨時局部變量可能是可讀性的最佳方式。我寧願堅持使用點符號,主要是爲了在代碼中保持一致。 我不知道爲什麼我沒有想到它,也許在我的腦海裏,我以爲我在浪費內存 - 但它只是另一個指針,而不是副本,所以它就是局部變量! 簡單而有效。謝謝。 :) – Jollino 2013-04-25 14:36:15

1

我想你很掙扎,因爲邏輯似乎放錯了位置。由於你的程序結構,這門語言與你打架,並不是因爲語言不完善。

子視圖的父類型是否真的合適?或者你是否通過在方形中填充一個圓形物體來違反Liskov替代原則?

您還可以問一下,從外部檢查BBBallView邏輯的內部是否真的合適?你能把邏輯轉移到合適的班級嗎?