1

作为序言,我是 iOS 开发的新手。我环顾四周试图找到答案,无论是在这里还是通过谷歌。

我的应用程序加载到带有注释的地图视图中。如果用户点击其中一个注释,则会显示带有附件按钮的标注视图。我遇到的问题在于点击附件按钮时调用的方法。我想显示特定注释的详细视图,但是当我点击附件按钮时,应用程序会因 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类代码 Header:

@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](空)

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。

感谢您的任何帮助!

4

7 回答 7

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 中有剩余的引用出口但您的控制器中的对象不再存在时。

您应该检查所有参考网点。

于 2011-07-12T22:44:13.497 回答
0

您的实施中有一些错误:

1)不要调用具有固定值的父方法:

self = [super initWithNibName:@"DetailViewController" bundle:nil];

而是使用参数:

self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

2) 您的 thetitle 和 thesubtitle 属性是 IBOutlet UILabel 但您使用复制而不是保留,通过保留更改复制

3)您在 init 方法中初始化 UILabel(标题和副标题)文本,但在此方法中,尚未定义属性(标题和副标题 = nil)。

您应该改用 NSString 属性,并使用您的 NSString 属性在 viewDidLoad 方法中设置 UILabel 的文本。

并对 UITextField 的描述属性执行相同的操作。

并且不要忘记释放在 dealloc 中复制或保留的所有属性,并在 viewDidUnload 方法中重置 IBOutlet 属性。

对于第 3 点:

将 NSString 属性添加到您的 DetailViewController 中(不要忘记在 dealloc 中合成并释放它):

@property (nonatomic, 保留) NSString *thetitleText;

接下来,在 pushViewController 之前,添加:

detailViewController.thetitleText = 标题;

最后在 DetailViewController 的 viewDidLoad 方法中,添加:

[标题集文本:self.thetitleText];

并为您的其他标签做同样的事情。

于 2011-07-12T23:01:45.310 回答
0

重新启动并创建一个新的细节视图控制器后,我很确定我的视图链接到图像而不是实际视图。更复杂的是,我也相信我的滚动视图真的把事情搞砸了。如果有人想查看实际有效的代码,请告诉我。感谢所有贡献的人!!SOverflow 是一个多么棒的社区啊!

于 2011-07-13T07:11:28.233 回答
0

确保您的视图控制器具有视图。正如问题中所述,我的正在轰炸(SIGABRT),因为我忘记在 IB 中将视图出口(通常在您的 xib 文件中为您创建)连接到我的控制器的视图。

于 2012-02-03T16:52:35.040 回答
0

仔细阅读代码...

确实使用以下方法进行了初始化object

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

为什么要这样重新分配object

object = [dictionary objectForKey:viewTitle];?

所以,不管在这个问题上,但这里有一个漏洞。另外,我很确定崩溃是由于object使用相应的键重新分配给该值,viewTitle稍后尝试向它发送消息,并且您只想操作 type 的对象PointOfInterest

希望这可以帮助。

于 2011-07-13T20:25:26.167 回答
0

我认为这是因为你有你的@property设置copy应该是retain

于 2011-07-12T22:35:03.223 回答
0

确保您的 XIB 中的文件所有者类别设置为 DetailViewController。

于 2011-07-12T22:39:14.600 回答