前言,我是iOS开发的新手。无论是在这里还是通过谷歌,我都已经环顾了一会儿,试着找到答案。
我的应用程序加载到带有注释的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]标注配件标记
2011-07-12 19:05:06.679 mkeBOAT [1687:ef03]美国银行大厦
2011-07-12 19:05:06.680 mkeBOAT [1687:ef03](null)
2011-07-12 19:05:06.680 mkeBOAT [1687:ef03](null),(null)
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 :(得分:3)
你不应该这样做
[detailViewController autorelease];
在将detailViewController推送到堆栈之前。
你应该首先将它推入导航堆栈,然后释放它,因为你不再需要它了,导航堆栈现在是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中有剩余的引用插座但是控制器中的对象不再存在时。
您应该检查所有引用网点。
答案 1 :(得分:0)
我认为这是因为您将@property
设置为copy
它应该是retain
答案 2 :(得分:0)
确保XIB中的文件类所有者设置为DetailViewController。
答案 3 :(得分:0)
您的实施中存在一些错误:
1)不要使用固定值调用父方法:
self = [super initWithNibName:@“DetailViewController”bundle:nil];
改为使用参数:
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
2)您的标题和副标题属性是IBOutlet UILabel,但您使用副本而不是保留,通过保留更改副本
3)您在init方法中初始化UILabel(thetitle和thesubtitle)文本,但在此方法中,尚未定义属性(thetitle和thesubtitle = nil)。
您应该使用NSString属性并使用NSString属性在viewDidLoad方法中设置UILabel的文本。
对UITextField描述属性也这样做。
不要忘记释放在dealloc中复制或保留的所有属性,并在viewDidUnload方法中重置您的IBOutlet属性。
关于第3点:
将NSString属性添加到DetailViewController(并且不要忘记在dealloc中合成并释放它):
@property(nonatomic,retain)NSString * thetitleText;
接下来,在pushViewController之前,添加:
detailViewController.thetitleText = title;
最后在DetailViewController的viewDidLoad方法中添加:
[thetitle setText:self.thetitleText];
为其他标签做同样的事情。
答案 4 :(得分:0)
重新启动并创建一个新的Detail View Controller后,我很确定我的视图链接到图像而不是实际视图。为了复合这一点,我也相信我的滚动视图真的很糟糕。如果有人想看到实际工作的代码,请告诉我。谢谢所有贡献者!!这是一个伟大的社区SOverflow!
答案 5 :(得分:0)
仔细阅读代码......
使用:
初始化object
PointOfInterest *object = [[PointOfInterest alloc] init];
。
为什么要像这样重新分配object
:
object = [dictionary objectForKey:viewTitle];
?
所以,无论在这个问题上,这里都是漏洞。此外,我很确定崩溃是由于object
重新分配viewTitle
对应密钥的值,尝试稍后向其发送消息,并且您只是想到操纵类型的对象PointOfInterest
。
希望这有帮助。
答案 6 :(得分:0)
确保您的View Controller具有视图。正如我在问题中所描述的那样轰炸(SIGABRT),因为我忘记在IB中将视图插座(通常是在你的xib文件中为你创建)连接到我的控制器视图。