2011-07-12 140 views
1

只是序言,我是iOS開發的新手。我環顧了一會兒,嘗試找到答案,無論是在這裏還是通過Google。將視圖控制器放到導航堆棧中導致SIGABRT

我的應用程序加載到帶有註釋的mapview中。如果用戶點擊其中一個註釋,會顯示帶附件按鈕的標註視圖。我遇到的問題是在點擊附件按鈕時調用的方法。我想要顯示特定註釋的細節視圖,但是當我點擊附件按鈕時,應用程序會與SIGABRT崩潰。

// method that provides the view for when the callout accessory button is tapped 
-    (void)mapView:(MKMapView *)mapView 
       annotationView:(MKAnnotationView *)view 
calloutAccessoryControlTapped:(UIControl *)control 
{ 
    // grabs the annotation's title from the annotation view 
    NSString *viewTitle = view.annotation.title; 

    // grabs corresponding POI object for map annotation 
    PointOfInterest *object = [[PointOfInterest alloc] init]; 
    object = [dictionary objectForKey:(NSString *)viewTitle]; 

    // assigns title and subtitle ivars to variables to be passed into detailviewcontroller init 
    NSString *title = object._title; 
    NSString *subtitle = object._subtitle; 
    UIImage *picture = object._picture; 
    NSString *description = object._description; 

    // releases POI object after all the information has been taken from it 
    [object release]; 

    // inits detailVC 
    DetailVC *detailVC = [[DetailVC alloc] initWithNibName:@"DetailVC" 
                bundle:[NSBundle mainBundle]]; 

    // sets the nsstring ivars in the DVC which correspond to the POI information 
    detailVC.thetitleText = title; 
    detailVC.thesubtitleText = subtitle; 
    detailVC.thepictureImage = picture; 
    detailVC.thedescriptionText = description; 

    // sets the "back" button on the navigation controller to say "Back to Map" 
    UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle:@"Back to Map" 
                     style:UIBarButtonItemStyleBordered 
                    target:nil 
                    action: nil]; 
    [[self navigationItem] setBackBarButtonItem: newBackButton]; 
    [newBackButton release]; 

    // pushes navcontroller onto the stack and releases the detail viewcontroller 
    [self.navigationController pushViewController:detailVC animated:YES]; 
    [detailVC release]; 
} 

我還沒有添加圖片和描述,因爲我只是想讓視圖顯示標題和副標題。

這裏是DetailViewController類代碼 部首:

@interface DetailViewController : UIViewController { 
    IBOutlet UIScrollView *scrollview; 
    IBOutlet UILabel *thetitle; 
    NSString *thetitleText; 
    IBOutlet UILabel *thesubtitle; 
    IBOutlet UIImage *thepicture; 
    IBOutlet UITextView *thedescription; 
} 

@property (nonatomic, retain) UIScrollView *scrollview; 
@property (nonatomic, retain) UILabel *thetitle; 
@property (nonatomic, retain) NSString *thetitleText; 
@property (nonatomic, retain) UILabel *thesubtitle; 
@property (nonatomic, retain) UIImage *thepicture; 
@property (nonatomic, retain) UITextView *thedescription; 

// method that creates the custom detail view with the corresponding information from 
// the point of interest objects 
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil title:(NSString*)title subtitle:(NSString *)subtitle picture:(UIImage *)picture description:(NSString *)description; 

@end 

實現:

@implementation DetailViewController 

@synthesize scrollview, thetitle, thesubtitle, thepicture, thedescription, thetitleText; 


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil title:(NSString *)title subtitle:(NSString *)subtitle picture:(UIImage *)picture description:(NSString *)description; 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
     NSLog(@"view initialized"); 
} 
return self; 
} 

- (void)dealloc 
{ 
    [scrollview release]; 
    [thetitle release]; 
    [thesubtitle release]; 
    [thepicture release]; 
    [thedescription release]; 
    [thetitleText release]; 
    [super dealloc]; 
} 

- (void)didReceiveMemoryWarning 
{ 
    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 

    // Release any cached data, images, etc that aren't in use. 
} 

#pragma mark - View lifecycle 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    NSLog(@"view did load"); 

    [thetitle setText:self.thetitleText]; 
    NSLog(@"thetitle text set"); 


// Do any additional setup after loading the view from its nib. 
// [thetitle setText:title]; 
// NSLog(@"set title"); 
// [thesubtitle setText:subtitle]; 
// NSLog(@"set subtitle"); 
// thepicture = picture; 
// [thedescription setText:description]; 
// NSLog(@"set description"); 
} 

這裏是SIGABRT輸出:

2011-07-12 19: 05:06.678 mkeBOAT [1687:ef03]標註配件Tap

2011-07-12 19:05:06.679 mkeBOAT [1687:ef03]美國銀行大廈

2011-07-12 19:05:06.680 mkeBOAT [1687:ef03](空)

2011-07-12 19:05:06.680 mkeBOAT [1687:ef03](空),(空)

2011-07-12 19:05:06.680 mkeBOAT [1687:ef03]視圖初始化

2011 -07-12 19:05:06.711 mkeBOAT [1687:ef03] *由於未捕獲異常而終止應用

'NSUnknownKeyException',原因:'[setValue:forUndefinedKey:]:該類不是密鑰描述符合密鑰值的密鑰值。

我不認爲字典工作正常,因爲它爲應該實際上有東西的值輸出null。

感謝您的幫助!

+0

你解決了這個布拉德利?看看我的回答 – 2011-07-13 20:26:00

+0

你的錯誤的描述似乎暗示字典不是用鍵種子,或者你的對象不能處理它給出的鍵值。你可以檢查POI對象是否可以處理你給的東西? – spamboy

回答

3

推detailViewController堆棧之前,你不應該這樣做

[detailViewController autorelease]; 

您應該先將其推入導航堆棧,然後釋放它,因爲您不再需要導航堆棧,導航堆棧現在是detailView控制器對象的所有者。

所以不是這樣

[detailViewController autorelease]; 

// this is the line that breaks with SIGABRT 
[self.navigationController pushViewController:detailViewController animated:YES]; 

做到這一點

[self.navigationController pushViewController:detailViewController animated:YES]; 
[detailViewController release]; 

更多信息:

SIGABRT當有剩餘您的IB引用網點,但在烏拉圭回合控制器對象通常發生已不存在了。

您應該檢查所有的參考插座。

+0

改變之後,仍然與SIGABRT崩潰。 –

+0

嘗試檢查所有參考插座。通常是sigbrt的原因 – 2011-07-12 22:49:41

+0

也試圖做到這一點 NSString * viewTitle = view.annotation.title; NSLog(@「%@」,viewTitle); 它可能是零 – 2011-07-12 22:51:11

0

我覺得是因爲你有你的@property設置爲copy應該retain

+0

對不起,請現在檢查。我貼了一些代碼。 –

+0

改變了這些,仍然存在問題。 –

0

確保文件的所有者在你的XIB類設置爲DetailViewController。

+0

檢查員窗口中的哪個位置可以更改? –

+0

單擊身份檢查器選項卡(Xcode 4中左起第三個)>自定義類>類。 –

+0

我可以改變它,但隨後它每次都會改回來。 –

0

。在你執行一些錯誤:

1)不要調用父類的方法與固定值:

自我= [超級initWithNibName:@ 「DetailViewController」 捆綁:無]。

而是使用參數:

自我= [超級initWithNibName:nibNameOrNil束:nibBundleOrNil];

2)你thetitle和thesubtitle性能IBOutlet中的UILabel,但你使用副本,而不是保留,以保留更改複印

3)您初始化您的UILabel(thetitle和thesubtitle)文本在init方法,但該方法中,該屬性尚未定義(thetitle和thesubtitle = nil)。

您應該改用NSString屬性,並使用NSString屬性在viewDidLoad方法中設置UILabel的文本。

併爲UITextField的描述屬性做同樣的事情。

不要忘記釋放您在dealloc中複製或保留的所有屬性,並在您的viewDidUnload方法中重置您的IBOutlet屬性。

對於點3:

添加的NSString屬性您DetailViewController(不要忘了合成和釋放它的dealloc中):

@屬性(非原子,保留)的NSString * thetitleText;

下,pushViewController之前,添加:

detailViewController.thetitleText =標題;

終於在你的DetailViewController你的viewDidLoad方法,添加:

[thetitle的setText:self.thetitleText]。

併爲您的其他標籤做同樣的事情。

+0

非常感謝您的幫助!在3) - (void)viewDidLoad { [super viewDidLoad]; //在從其筆尖加載視圖後執行其他任何設置。 [thetitle setText:title]; NSLog(@「set title」);說我不能引用標題,我如何將該參數傳遞給viewdidload函數?如何在不提交它的情況下在stackoverflow註釋中添加新行? –

+0

'init'方法點是個人喜好的問題。如果另一個對象告訴'viewController'使用了什麼xib,我傾向於認爲它打破了封裝 - 這意味着另一個對象比'viewController'本身知道得更好。因此,我刪除了'nibName'和'bundle'選項並將它們保留在內部。 –

+0

您需要爲呈現視圖控制器之前設置的NSString標題擁有一個屬性,我編輯了我的答案以向您展示如何做到這一點。 Shift + Enter轉到一個新行,但不會在您提交註釋時添加新行 – Johnmph

0

重新啓動並創建一個新的詳細視圖控制器後,我很確定我有我的視圖鏈接到圖像,而不是實際的視圖。爲了加強這一點,我也相信我的scrollview真的讓事情變得糟糕起來。如果有人希望看到實際工作的代碼,請告訴我。感謝所有捐助!多麼好的社區SOverflow!

0

仔細閱讀代碼...

使用初始化object

PointOfInterest *object = [[PointOfInterest alloc] init];

爲什麼要重新分配object像這樣:

object = [dictionary objectForKey:viewTitle];

所以,無論在這個問題上,但這裏是一個泄漏。另外,我很確定這次崩潰是由於objectviewTitle對應鍵的值重新分配,試圖稍後向它發送消息,以及您只是想到操縱PointOfInterest類型的對象。

希望這會有所幫助。

+0

我應該如何重新分配'object'? –

+0

我解決了SIGABRT問題,但當我深入細節視圖並回溯幾次時,我仍然在應用程序中發生一些崩潰行爲。 –

+0

你不應該。一旦你初始化你的對象,設置它的屬性與你在'[dictionary objectForKey:viewTitle];' – 2011-07-14 10:24:55

0

確保您的視圖控制器有一個視圖。就像問題中所描述的那樣,我正在轟炸(SIGABRT),因爲我忘記了IB將視圖插座(通常是在您的xib文件中爲您創建的)連接到控制器視圖。

相關問題