2012-06-07 41 views
0

我一直在搜索頂部和底部的信息如何做到這一點。我登陸了一個很棒的教程!所以我對此仍然很陌生。基本上我一直試圖將Map View註釋存儲到數組中。註釋是一個獨立的類,它基本上覆蓋/作爲引腳註釋的MKAnnotation。它有三個屬性:保存多個地圖註釋 - 崩潰

  1. 標註座標
  2. 註釋標題
  3. 註釋字幕

這個數組需要存儲到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它用於NSCodingMKAnnotation:如下面< 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]; 

回答

0

我已經解決了這個問題!我來實現,座標兩個變量,經度和緯度是雙打,數據類型...不是對象!因此,他們只是堅持和工作,因爲它們被複制......不同於引用的對象。長話短說我需要retain。就像這樣:

 title = [[aDecoder decodeObjectForKey: @"titler"] retain]; 
     subtitle = [[aDecoder decodeObjectForKey: @"subtitler"] retain]; 
1

我不確定究竟是什麼原因造成的崩潰。但我注意到在您的編碼/解碼方法的一些錯誤:

編輯:只有當您的超類符合NSCoding:

在encodeWithCoder你應該在第一次調用:

[super encodeWithCoder: aCoder]; 

在的initWithCoder更換

self = [super init]; 

通過

self = [super initWithCoder:aDecoder] 

下返回不可變對象(不NSMutableArray的):

localOverlays = [NSKeyedUnarchiver unarchiveObjectWithData: data]; 

通過替換此行:

localOverlays = [[NSKeyedUnarchiver unarchiveObjectWithData: data] mutableCopy]; 

我希望幫助!

+0

嗯....我得到一個警告,說超級沒有響應選擇器encodeWithCoder和initWithCoder,因爲它是NSObject而非NSCoding。 – MCKapur

+0

Ahhh我看到我在我的問題中做了一些錯誤,Annotation不符合NSCoder ... – MCKapur

+0

檢查我更新的問題 – MCKapur