xcode 无法在 NSManagedObject 类上调用指定的初始化程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6752108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Failed to call designated initializer on NSManagedObject class
提问by 5lb Bass
Another newbie question, just when I thought I was beginning to get a very small handle on ios programming. Ugh! I'm following a tutoria from the appcodeblog.com where I'm building a simple tab bar application utilizing core data to enter, display, and search vacation destinations. I've worked through the tutorial and have a working app, but I notice when I select the "Show Destinations" tab I get the following error. The app seems to continue working, but the error is logged to the console. I'm trying to debug the issue and understand exactly what is happening, but I just don't quite understand what is wrong. I "think" I have an issue with my ShowDestinations.xib file where I've incorrectly hooked up my objects within the xib. Any help is MUCH appreciated. Thanks in advance for your help and time.
另一个新手问题,就在我以为我开始对 ios 编程有所了解的时候。啊! 我正在关注 appcodeblog.com 上的教程,我正在使用核心数据构建一个简单的标签栏应用程序,以输入、显示和搜索度假目的地。我已经完成了本教程并有一个可以运行的应用程序,但是我注意到当我选择“显示目的地”选项卡时出现以下错误。该应用程序似乎继续工作,但错误记录到控制台。我正在尝试调试问题并确切了解发生了什么,但我不太明白出了什么问题。我“认为”我的 ShowDestinations.xib 文件有问题,我错误地将我的对象连接到了 xib 中。任何帮助深表感谢。
Here's the error, "CoreDataTabBarTutorial[1262:207] Failed to call designated initializer on NSManagedObject class 'Destination'.
这是错误,“CoreDataTabBarTutorial[1262:207] 无法调用 NSManagedObject 类“目标”上的指定初始值设定项。
I'm not sure what code to provide so I've started out by showing my header and implementation files ShowDistinationsViewController.h and ShowDestinationsViewController.m
我不确定要提供什么代码,所以我首先展示了我的头文件和实现文件 ShowDistationsViewController.h 和 ShowDestinationsViewController.m
ShowDistinationsViewController.h
ShowDistinctionsViewController.h
#import <UIKit/UIKit.h>
@interface SearchDestinationsViewController : UIViewController {
UISearchBar *destinationSearchBar;
UITableView *searchTableView;
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
NSArray *fetchedObjects;
}
@property (nonatomic, retain) IBOutlet UISearchBar *destinationSearchBar;
@property (nonatomic, retain) IBOutlet UITableView *searchTableView;
@property (nonatomic, retain) IBOutlet NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) IBOutlet NSManagedObjectContext *managedObjectContext;
@end
ShowDestinationsViewController.m
ShowDestinationsViewController.m
#import "ShowDestinationsViewController.h"
#import "Destination.h"
@implementation ShowDestinationsViewController
@synthesize destinationsTableView;
@synthesize destinationsArray;
@synthesize fetchedResultsController;
@synthesize managedObjectContext;
// Not sure where the following code came from so I commented it out!!! It didn't seem to break anything when I commented it out
//- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
//{
// self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
// if (self) {
// // Custom initialization
// }
// return self;
//}
- (void)dealloc
{
[destinationsArray release];
[destinationsTableView 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
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
*/
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark -
#pragma Data Fetch from Core Data
- (void) viewWillAppear:(BOOL)animated
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Destination" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil)
{
// Handle the error.
NSLog(@"mutableFetchResults == nil");
}
[self setDestinationsArray:mutableFetchResults];
[request release];
[destinationsTableView reloadData];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [destinationsArray count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
Destination *destination = [[Destination alloc] init];
destination = (Destination *)[destinationsArray objectAtIndex:indexPath.row];
cell.textLabel.text = destination.name;
[destination release];
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
@end
回答by Yuji
The problem seems to lie in
问题似乎在于
Destination *destination = [[Destination alloc] init];
destination = (Destination *)[destinationsArray objectAtIndex:indexPath.row];
[destination release];
The first line is unnecessary: In Objective-C, Destination*
is a pointer to the object, not the real object. The Destination
object you want is presumably already in the array. So you don't have to create an object to point to, in the line [[Destination alloc] init]
, which is gone immediately at the next line. What's going on was
第一行是不必要的:在 Objective-C 中,Destination*
是指向对象的指针,而不是真正的对象。Destination
你想要的对象大概已经在数组中了。因此,您不必在行中创建要指向的对象,该对象[[Destination alloc] init]
在下一行立即消失。发生了什么事
[[Destination alloc] init]
creates an objecta
,destination
points toa
.a
is retained by you.(Destination *)[destinationsArray objectAtIndex:indexPath.row]
gives you another objectb
, which is not retained by you.destination
now points tob
. No one holdsa
any longer.release
is sent to the object pointed to bydestination
, i.e., tob
. This is against the retain-release rule; you should releasea
, notb
!
[[Destination alloc] init]
创建一个对象a
,destination
指向a
.a
由您保留。(Destination *)[destinationsArray objectAtIndex:indexPath.row]
给你另一个对象b
,它不是你保留的。destination
现在指向b
. 没有人再持有了a
。release
被发送到指向的对象destination
,即,到b
。这违反了保留释放规则;你应该释放a
,而不是b
!
So, instead, just do
所以,相反,只是做
Destination *destination = (Destination *)[destinationsArray objectAtIndex:indexPath.row];
without the release
part.
没有release
部分。
As an advice: always run Analyze
(which is available below the Build
menu) when you build your project. The analyzer is designed to catch common types of errors, including yours. Correct your code so that all the analyzer warnings go away; you should always regard the analyzer warning as an error on your part.
建议:在构建项目时始终运行Analyze
(可在Build
菜单下方找到)。分析器旨在捕获常见类型的错误,包括您的错误。更正您的代码,使所有分析器警告消失;您应该始终将分析器警告视为您的错误。