2009-09-04 24 views
2

我有一個iPhone應用程序,它在任何給定的時間處理25,000個地方的子集。如何維護對象的全局緩存? (或NSMutableSet不保留的內容)

我想維護位置緩存,以便我知道如果我的應用程序的某個部分更新了某個位置,則知道該位置的其他每個部分都會看到該更新。

我最初的實現是創建一個NSMutableSet來存儲對緩存地點的引用。

找到新位置的方法將首先檢查緩存並返回緩存的對象,或者如果位置不在緩存中,它們將創建一個新的位置對象並將其添加到緩存中。

問題是如何釋放不再需要的對象?

NSMutableSet將保留這個位置,所以retainCount永遠不會變爲零,並且dealloc永遠不會被調用。

是否有一個Kosher方法來處理髮布方案?有沒有其他的模式可以做到這一點,我不知道。

(CoreData目前不是一個選項,但我明白它可以處理這個問題)。

謝謝

回答

0

使用的核心數據,如果你能部署到的iPhoneOS 3.0或更高版本,或者使用SQLite爲的iPhoneOS 2.x的無論哪種方式,您都可以使用數據庫來存儲數據,並且您將能夠執行查詢以獲取最新的數據集。

+1

我現在正在使用SQLite。我不希望在視圖重新出現時不必重新加載視圖中的所有對象,只是因爲它們中的一個可能已經改變,所以我想要一種方法將一個地方的變化傳達給所有其他viewController,掛在它上面。 – 2009-09-04 04:15:07

3

在桌面上,你可以使用NSPointerSet來做到這一點,在iPhone上它有點困難。

可以使用的CoreFoundation創建一個非固定設置,如果你真的想:

//Default callbacks 
CFSetCallBacks callbacks = kCFTypeSetCallBacks; 

//Disable retain and release 
callbacks.retain = NULL; 
callbacks.release = NULL; 

cachedPlaces = (NSMutableSet *)CFSetCreateMutable(kCFAllocatorDefault, 
             0, 
             &callbacks); 

這使得非固定集。請注意,當它們被釋放時,您仍然需要從集合中刪除對象,否則您的集合中將會有陳舊的指針,這會導致您在deref上崩潰。所以在對象要添加到設置您需要的dealloc是這樣的:

- (void)dealloc { 
    [cachedPlaces removeObject:self]; 

    [super dealloc]; 
} 

這是唯一真正適合現存文獻的純粹在內存緩存,如果您還需要移動的東西,並從然後CoreData基本上爲您處理所有這些。

+0

,看起來正是我想要的。我會試試看。使用NSMutableSet的 – 2009-09-04 04:31:14

+0

不是很正確的結構,因爲沒有getObjectEqualToObject:方法或類似的東西。我正在嘗試一本字典。 – 2009-09-04 07:45:53

+0

我無法編譯示例代碼Places類。 「初始化元素不是恆定的」 我想創建一個類變量。 – 2009-09-04 08:00:41

1

你可以使用NSMutableSet作爲高速緩存,並依靠事實,即它包含的1擋計數的任何對象只能由高速緩存所擁有。因此,以1:1的保留計數的任何對象應該被刪除,這是很容易做到:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"retainCount > 1"]; 
[cachedPlaces filterUsingPredicate:predicate]; 

做這個計時器,或者每當一個地方添加和/或刪除,如果是不要過於頻繁。您也可以使謂詞靜態以避免每次都生成一個新實例。

0

由於iOS的4.0,要做到這一點,正確的方法是使用NSCache。當系統發送低內存警告時,它可以自動清除對象。您還可以設置緩存大小限制。

NSCache Class Reference

0

這個問題是老了,但我最近碰到一個類似的問題就來了。我相信使用NSHashTable可以適應這種情況的要求。

NSHashTable比NSCache或NSSet更好,因爲它可以容納對你的實例的弱引用,這樣一旦所有引用都被刪除,實例就會自動從NSHashTable中移除,這要歸功於ARC。這可以作爲一種「即時」緩存方法,只保留強引用在別處保存的對象。

考慮到您有多個可添加引用的應用程序部分,使用NSHashTable作爲Flyweight Pattern的享元池可能會有用。 Flyweight模式的第二部分需要一個工廠,工廠將負責檢查池中的實例,如果未找到該實例,則將其添加到池中,然後返回池中的實例。