2011-07-12 149 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文件中为您创建的)连接到控制器视图。

相关问题