我一直在搜索頂部和底部的信息如何做到這一點。我登陸了一個很棒的教程!所以我對此仍然很陌生。基本上我一直試圖將Map View註釋存儲到數組中。註釋是一個獨立的類,它基本上覆蓋/作爲引腳註釋的MKAnnotation
。它有三個屬性:保存多個地圖註釋 - 崩潰
- 標註座標
- 註釋標題
- 註釋字幕
這個數組需要存儲到NSUserDefaults
。我面臨的一個問題,這裏是日誌:
[UIMutableIndexPath的setObject:forKey:]:無法識別的選擇發送到 實例存儲陣列內0x1187b0
我的註釋類對象無法保存到用戶默認。所以我不得不把這個數組變成NSData
然後保存它,對吧?
我有很多代碼設置,只是不工作。這裏是我嘗試了這一切:
視圖控制器Class.m:
- (void)syncMap { // this method is called in viewWillDissapear (for running tests) and applicationDidEnterBackground in App Delegate
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: localOverlays]; // this is the array I was talking about
[defaults setObject:data forKey:@"overlays"];
[defaults synchronize];
}
- (void)initCircles { // called in AppDelegate UIApplicationDelegate method: applicationDidFinishLaunchingWithOptions
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey: @"overlays"];
localOverlays = [NSKeyedUnarchiver unarchiveObjectWithData: data];
if (!localOverlays) {
// Either there is a problem or it is the first time opening the app
localOverlays = [[NSMutableArray alloc] init];
}
}
注:我與兩個註解TESTING在Array(localOverlays
)
所以,我localOverlays
可編碼/存檔(使用NSCoder
),因爲它是NSArray
。但是,我不得不在Annotation類中添加一些進一步的設置。在它的.h它用於NSCoding
和MKAnnotation
:如下面< NSCoding, MKAnnotation>
。對不起,如果我不使用正確的術語。這裏是我的.m:
- (void)encodeWithCoder:(NSCoder *)aCoder { // should only be called when app enters background state, but since that cannot log in the console, like before I set it up so it should also be called in viewWillDissapear
NSLog(@"encodeCoder called in Annotation"); // gets called twice when the view will disappear... GOOD!
[aCoder encodeObject: title forKey: @"title"];
[aCoder encodeObject: subtitle forKey: @"subtitle"];
[aCoder encodeDouble: coordinate.latitude forKey: @"latitude"];
[aCoder encodeDouble: coordinate.longitude forKey: @"longitude"];
}
- (id)initWithCoder:(NSCoder *)aDecoder { // Should be called only at startup of app (not the first time you startup the app though... because data will be NULL)
NSLog(@"In the Annotation class, initWithCoder is called"); // Does get called at appropriate times twice... NICE!
self = [super init];
if (self) {
title = [aDecoder decodeObjectForKey: @"title"];
subtitle = [aDecoder decodeObjectForKey: @"subtitle"];
double lat = [aDecoder decodeDoubleForKey: @"latitude"];
double lon = [aDecoder decodeDoubleForKey: @"longitude"];
coordinate = CLLocationCoordinate2DMake(lat, lon);
}
return self;
}
所以,你可以看到,我有一切設置存檔,對吧?那麼它似乎不是...因爲現在在視圖控制器的.M,我也有這個代碼在viewDidLoad中:
for (Annotation *pin in localOverlays) {
if (pin) {
NSLog(@"valid pin: _CMD updateCircles");
[mapView addAnnotation: pin];
}
}
此代碼很好地工作和精細的第一次我打開我的應用程序,並添加引腳。好吧,現在我已退出視圖並退出應用程序,並從多任務欄中刪除。當我打開它回來了,我在快速列舉線得到一個崩潰:
-[NSURL countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0xcd31140
那麼,有什麼不對我所有的歸檔和編碼設置。這裏有什麼問題......我知道這是一個漫長的問題,但我試圖很好地構建它。我是否設置了我的代碼完全不正確,我的代碼中是否有錯字/錯誤?謝謝大家!
UPDATE:
我有編碼的座標變量,因此當我腳後啓動的應用程序出現在正確的座標,但是當我嘗試按它看到標題和副標題,我得到的下面的崩潰:
objc_msgSend
因此,東西被釋放正確......只是一個猜測......糟糕的內存管理?什麼會導致我的代碼崩潰?
UPDATE:
我已經看過更深更遠到我的代碼和改變周圍的幾個release
語句,只是提高了我的內存管理和做了一些優化。現在我得到一個更具體的崩潰:
*** -[CFString length]: message sent to deallocated instance 0x147490
所以我的標題或小標題被釋放......爲什麼?我檢查了我的代碼,它應該是絕對沒問題,特別是因爲座標都很好...
UPDATE:
我已經解決了這個問題!我來實現,座標兩個變量,經度和緯度是雙打,數據類型...不是對象!因此,他們只是堅持和工作,因爲它們被複制......不同於引用的對象。長話短說我需要retain
。就像這樣:
title = [[aDecoder decodeObjectForKey: @"titler"] retain];
subtitle = [[aDecoder decodeObjectForKey: @"subtitler"] retain];
嗯....我得到一個警告,說超級沒有響應選擇器encodeWithCoder和initWithCoder,因爲它是NSObject而非NSCoding。 – MCKapur
Ahhh我看到我在我的問題中做了一些錯誤,Annotation不符合NSCoder ... – MCKapur
檢查我更新的問題 – MCKapur