![](/img/trans.png)
[英]Memory management in iOS , Simulator vs idevice gives different result
[英]Internal memory in iOS simulator
我剛剛完成了iOS開發的第二個教程。 當我添加新的瞄准點時,它可以正常工作並出現在瞄准點列表中。 但是,當我關閉iOS模擬器並重新打開它時,只有第一個條目存在(它是手動添加的)。 即使關閉並重新打開,iOS模擬器中也應該有內部存儲器嗎? 似乎有些記憶,好像我將聯系人信息添加到聯系人中一樣,當我重新打開它時它仍然存在。 如果是這樣,我如何確保DataController文件中的數組以類似的方式存儲在模擬器/電話中,以便每次重新打開模擬器時都不會清除自身?
謝謝
如果要在會話之間保存數據,則需要使用永久性存儲。 選項包括:
您可以使用plist文件。 例如,如果您有NSArray *array
,則可以使用writeToFile
將其保存到plist:
[array writeToFile:filename atomically:YES];
然后,您可以使用以下命令讀取此數組:
NSArray *array = [NSArray arrayWithContentsOfFile:filename];
但是,此技術僅適用於標准NSString
, NSNumber
等對象,不適BirdSighting
類的自定義對象。
對於如BirdSighting
這樣的自定義對象,可以使用NSKeyedArchiver
和NSKeyedUnarchiver
。 順便說一句,這些不僅是用於保存此類小數據集數據的通用類,而且考慮到它在新的iOS 6狀態保存功能中的顯着特征,值得您熟悉這種模式。
您可以使用NSUserDefaults
。 這確實更適合於應用程序設置和默認設置,但理論上也可以用於保存數據。
您可以使用CoreData 。 這是用於對象持久性的首選iOS技術。 它是一個功能強大且設計精良的框架(雖然有點復雜),並且如果您要處理大量數據,則非常適合。
您也可以使用SQLite 。 請參閱Ray Wenderlich的有關使用SQLite的文章 。 並且,一旦開始使用SQLite,就可以考慮使用FMDB來簡化編碼工作。
例如,如果您想使用第二種方法NSKeyedArchiver
和NSKeyedUnarchiver
,那么您可能要做的第一件事就是通過更改BirdSighting.h
的@interface
聲明使BirdSighting
符合NSCoding
:
@interface BirdSighting : NSObject <NSCoding>
其次,您必須在BirdSighting.m
中編寫兩個NSCoding
方法initWithCoder
和encodeWithCoder
,它們定義了可以為此對象加載/保存的屬性:
- (NSArray *)keysForEncoding;
{
return @[@"name", @"location", @"date"];
}
- (id) initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
for (NSString *key in [self keysForEncoding])
{
[self setValue:[aDecoder decodeObjectForKey:key] forKey:key];
}
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
for (NSString *key in self.keysForEncoding)
{
[aCoder encodeObject:[self valueForKey:key] forKey:key];
}
}
您BirdSighting
現在可以加載和保存與NSKeyedUnarchiver
和NSKeyedArchiver
分別。
因此,着重於瞄准點的加載,您必須(a)告訴BirdSightingDataController.m
要查找什么文件; (b)指示它在初始化期間讀取該文件:
- (NSString *)filename
{
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
return [docsPath stringByAppendingPathComponent:@"BirdSightings"];
}
- (void)initializeDefaultDataList
{
NSString *filename = [self filename];
self.masterBirdSightingList = nil;
if ([[NSFileManager defaultManager] fileExistsAtPath:filename])
{
self.masterBirdSightingList = [NSKeyedUnarchiver unarchiveObjectWithFile:filename];
}
if (!self.masterBirdSightingList)
{
NSMutableArray *sightingList = [[NSMutableArray alloc] init];
self.masterBirdSightingList = sightingList;
BirdSighting *sighting;
NSDate *today = [NSDate date];
sighting = [[BirdSighting alloc] initWithName:@"Pigeon" location:@"Everywhere" date:today];
[self addBirdSightingWithSighting:sighting];
}
}
BirdSightingDataController.m
也可以定義一種保存數據的方法:
- (BOOL)save
{
return [NSKeyedArchiver archiveRootObject:self.masterBirdSightingList toFile:[self filename]];
}
例如,您現在可以在添加瞄准點時調用此save
方法,例如:
- (void)addBirdSightingWithSighting:(BirdSighting *)sighting
{
[self.masterBirdSightingList addObject:sighting];
[self save];
}
就個人而言,我寧願讓我的應用程序委托在應用程序進入后台或終止時保存它,而不是每次用戶對應用程序進行任何更改時都保存它(但這需要進一步的更改,因此我不再贅述)現在)。
但是希望該代碼說明了如何使用NSKeyArchiver
和NSKeyUnarchiver
保存和加載數據。 顯然,對於更復雜的場景,我通常會建議您考慮核心數據。 但是對於像這樣的小型數據集,此存檔器模式可能會有用(並且正如我所說的,因為在iOS 6應用程序狀態還原中也使用了基本技術,因此值得熟悉)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.