2013-06-20 62 views
2

我正在使用核心數據,並試圖將表視圖單元添加到視圖控制器中的表視圖。當我在表格視圖控制器中實現它時,應用程序運行。當我在表視圖是另一個視圖控制器的一部分時運行它時,該應用程序無法運行。它在代碼中顯示錯誤:在DeviceViewController類型的對象上找不到屬性tableview。 DeviceViewController.h有一個表視圖數據源和委託。我的代碼是:使用核心數據的View Controller中的表視圖

#import "DeviceViewController.h" 
#import "DeviceDetailViewController.h" 

@interface DeviceViewController() 
@property (strong) NSMutableArray *devices; 
@end 

@implementation DeviceViewController 

- (NSManagedObjectContext *)managedObjectContext { 
NSManagedObjectContext *context = nil; 
id delegate = [[UIApplication sharedApplication] delegate]; 
if ([delegate performSelector:@selector(managedObjectContext)]) { 
context = [delegate managedObjectContext]; 
} 
return context; 
} 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
if (self) { 
// Custom initialization 
} 
return self; 
} 
- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

// self.navigationItem.rightBarButtonItem = self.editButtonItem; 
}  

- (void)viewDidAppear:(BOOL)animated 
{ 
[super viewDidAppear:animated]; 

// Fetch the devices from persistent data store 
NSManagedObjectContext *managedObjectContext = [self managedObjectContext]; 
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Device"]; 
self.devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil]    mutableCopy]; 

[self.tableView reloadData]; 
} 

- (void)didReceiveMemoryWarning 
{ 
[super didReceiveMemoryWarning]; 
// Dispose of any resources that can be recreated. 
} 

#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 self.devices.count; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath  *)indexPath 
{ 
static NSString *CellIdentifier = @"Cell"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier   forIndexPath:indexPath]; 

// Configure the cell... 
NSManagedObject *device = [self.devices objectAtIndex:indexPath.row]; 
[cell.textLabel setText:[NSString stringWithFormat:@"%@ ", [device valueForKey:@"name"]]]; 

return cell; 
} 


- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
// Return NO if you do not want the specified item to be editable. 
return YES; 
} 


    - (void)tableView:(UITableView *)tableView commitEditingStyle:  (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
NSManagedObjectContext *context = [self managedObjectContext]; 

if (editingStyle == UITableViewCellEditingStyleDelete) { 
// Delete object from database 
[context deleteObject:[self.devices objectAtIndex:indexPath.row]]; 

NSError *error = nil; 
    if (![context save:&error]) { 
NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]); 
return; 
} 

// Remove device from table view 
[self.devices removeObjectAtIndex:indexPath.row]; 
[self. otableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]   withRowAnimation:UITableViewRowAnimationFade]; 
    } 
} 

回答

0

正如我所看到的,在這種情況下,它與CoreData無關。

您應該將UITableViewDataSourceUITableViewDelegate協議添加到您的VC。 之後,你應該創建一個UITableView(你可以在界面生成器中完成)並將數據源和委託連接到你的視圖控制器。

您還可以在VC中爲UITableView添加一個屬性。

當您使用UITableViewController時,所有這些都是從Xcode完成的,但是如果在常規UIViewController內使用UITableView,則應該照顧這些東西。

祝你好運!

編輯:

添加爲PROPERT

@property (nonatomic, strong) UITableView *deviceTableView; 

更改viewDidLoad方法是:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    _deviceTableView = [[UITableView alloc] initWithFrame:self.view.frame]; 
    _deviceTableView.delegate = self; 
    _deviceTableView.dataSource = self; 
    [self.view addSubview:_deviceTableView]; 
    [_deviceTableView reloadData]; 
} 

刪除你寫在viewDidAppear什麼,並與_deviceTableView取代self.tableView無處不在這個文件。

+0

我這樣做了,但加載時會崩潰。顯示SIGBART錯誤 –

+0

您得到的異常消息是什麼? –

+0

我改變了一些東西,並將其添加到我的viewdidappear函數中: DeviceViewController * deviceViewController = [[DeviceViewController alloc] init]; deviceViewController.tableView = self.tableView; self.tableView.dataSource = deviceViewController; self.tableView.delegate = deviceViewController; 現在,它顯示[self.tableView reloadData]上的斷點; –

0

可能導致崩潰的另一個問題是,如果您嘗試執行提取請求時,您的NSManagedObjectContext爲零。在將它用於任何視圖層次結構方法之前,我會添加if([self managedObjectContext])

另外,使用從故事板實例化的視圖時應該小心。 Nikola的回答說要在viewDidLoad中添加配置視圖控制器的代碼,只要您沒有將UITableView拖放到界面構建器中的UIViewController實例上即可。如果您已經在界面構建器中創建並鏈接了一個tableview,那麼您將不必要地將其替換爲新的,因此在使用_deviceTableView = [[UITableView alloc] initWithFrame:self.view.frame]之前; 行,您應該添加一條if(!_deviceTableView) 聲明,因爲它會阻止您向視圖添加第二個表視圖。問題是,如果你已經在IB中添加了一個tableview,即使你改變了你的tableview屬性,它也會被你的視圖保留下來,所以有可能出現兩個表格。

或者,您可以在getter方法中爲表視圖屬性使用「lazy instantiation」,以確保在訪問它時初始化它。

最後,爲了幫助我們更好地瞭解您的應用程序崩潰的原因,從Xcode中的控制檯獲取異常日誌會很有幫助。

+0

我認爲問題是當NSManagedObjectContext執行獲取請求時,請告訴我要寫什麼代碼。 –

+0

我知道viewdidappear函數有什麼問題,我只是不知道如何改變它,請你幫我 –

+0

我在viewDidAppear函數中注意到了更多的東西,它們都不能直接關聯到崩潰,但他們都是你可能想要解決的問題。首先,在您的managedObjectContext getter中,如果您可能需要'respondsToSelector:',則調用'if([delegate performSelector:@selector(managedObjectContext)])',因爲如果performSelector不存在,performSelector仍會使您的應用程序崩潰。第二件事情是,當一個提取請求用於tableview時,你必須使用一個排序描述符,這樣每次執行它時對象就會以相同的順序返回。 – mrosales

相關問題