正在跳过详细视图控制器中的第一种方法

时间:2012-11-28 04:03:43

标签: objective-c ios core-data uiviewcontroller

RoomItem中是否需要一些重要的东西来确保不跳过此方法?它是我的详细视图控制器中的第一个,当我处于调试模式时,它会不断跳过。我确定我错过了一些非常简单的东西,但我已经盯着它看了好几个小时而且无法弄清楚它是什么。

@interface DetailViewController ()
- (void)configureView;
@end
@implementation DetailViewController
- (void)setDetailItem:(RoomItem *)newDetailItem
{
    if (_detailItem != newDetailItem) {
        _detailItem = newDetailItem;

        // Update the view.
        [self configureView];
    }
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
    [_roomTxt setText:[_detailItem room]];
    [_buildingTxt setText:[_detailItem building]];
    [_dateTxt setText:[self dateCreatedString]];
    [_buildingImageView setImage:[_detailItem buildingImage]];
    _oi = [_detailItem objectIndex];
}
}

分配和初始化新的和现有的detailViewControllers的MasterViewController(根表视图)方法

- (void)insertNewObject:(id)sender
{
//add button invokes this
DetailViewController *ivc = [[DetailViewController alloc] init];
[self.navigationController pushViewController:ivc animated:YES];
NSLog(@"detailViewController allocated and initialized: %@", ivc);
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.detailViewController) {
    self.detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
    NSLog(@"detailViewController initialized: %@", self.detailViewController);
}
//navigates to detailViewController and passes it the item's data
self.detailViewController.detailItem = [[[RoomList sharedStore] getAllItems] objectAtIndex:[indexPath row]];
[self.navigationController pushViewController:self.detailViewController animated:YES];
}

这是tableView:didSelectRowAtIndexPath方法,该方法应传递详细视图控制器所需的所有内容,来自RoomList:sharedStore:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.detailViewController) {
    self.detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
}
//navigates to detailViewController and passes it the item's data
self.detailViewController.detailItem = [[[RoomList sharedStore] getAllItems] objectAtIndex:[indexPath row]];
[self.navigationController pushViewController:self.detailViewController animated:YES];
}

...和RoomItem.m文件:

- (void)awakeFromFetch
{
[super awakeFromFetch];

UIImage *pic = [UIImage imageWithData:[self buildingThumbnailData]];
[self setPrimitiveValue:pic forKey:@"buildingThumbnail"];
}
- (id)initWithRoom:(NSString *)room Building:(NSString *)building 
{
self = [super init];
if (self) {
    [self setRoom:room];
    [self setBuilding:building];
}
return self;
}

DetailViewController.h

#import <UIKit/UIKit.h>
@class RoomItem;
//pic edit: added delegates
@interface DetailViewController : UIViewController <UINavigationControllerDelegate,
UIImagePickerControllerDelegate, UITextFieldDelegate, UIPopoverControllerDelegate,
UIPageViewControllerDelegate>
{
__weak IBOutlet UITextField *roomField;
__weak IBOutlet UITextField *buildingField;
__weak IBOutlet UILabel *dateLabel;

UIPopoverController *imagePickerPopover;
}
@property (nonatomic, strong) RoomItem *detailItem;
@property (weak, nonatomic) IBOutlet UIButton *updateBtn;
@property (weak, nonatomic) IBOutlet UIButton *detailsBtn;
@property (weak, nonatomic) IBOutlet UITextField *roomTxt;
@property (weak, nonatomic) IBOutlet UITextField *buildingTxt;
@property (weak, nonatomic) IBOutlet UILabel *dateTxt;
@property (weak, nonatomic) IBOutlet UIImageView *buildingImageView;
@property (weak, nonatomic) UIImage *buildingImage;
@property (weak, nonatomic) NSNumber *oi;
- (IBAction)backgroundTapped:(id)sender;
- (IBAction)takePicture:(id)sender;
- (IBAction)updateRoomItem:(id)sender;
- (IBAction)goToReportDetails:(id)sender;
@end

编辑:这是一个伪UML图,说明了我在调试器中执行操作时所看到的内容(从左到右,从上到下读取): enter image description here

2 个答案:

答案 0 :(得分:1)

没有调用setter是很奇怪的。我会采取行

self.detailViewController.detailItem = [[[RoomList sharedStore] getAllItems] objectAtIndex:[indexPath row]];

并将其替换为可能更容易理解的代码:

RoomItem *tempItem = [[[RoomList sharedStore] getAllItems] objectAtIndex:[indexPath row]];
DetailViewController *tempDVC = self.detailViewController; // could just use _detailViewController
tempDVC.detailItem = tempItem;  // breakpoint on this line

然后当断点命中时,我会单步执行编译后的汇编程序以找出它的去向。 Xcode Debugger - how to single step at level of CPU instructions有相关说明 - 特别是几周前Max MacLeod的答案。

我已经把它写成另一条评论,因为它不是一个真正的答案,但它太长了!

答案 1 :(得分:0)

好的,首先是第一件事。原因 - (void)setDetailItem:(RoomItem *)newDetailItem被跳过是因为我没有在DVC中传递新创建的RoomItem。我最初这样做,但在试图纠正其他地方的问题时错误地摆脱了它。

在DetailViewController.m中:

- (void)insertNewObject:(id)sender
{
RoomItem *newItem = [[RoomList sharedStore] createItem];

DetailViewController *ivc = [[DetailViewController alloc] init];

[ivc setDetailItem:newItem];

[self.navigationController pushViewController:ivc animated:YES];
NSLog(@"detailViewController allocated and initialized: %@", ivc);
}

让这个工作虽然在RoomList.m文件中进行了一些重组。我最初尝试将创建和更新函数结合到一个方法中。如果我在MVC中创建并在DVC中更新,那就不会飞。

所以我将两者分开:

- (RoomItem *)createItem
{
double order;

//create new roomItem
//tracks what number item it's creating
if ([allItems count] == 0) {
    order = 1.0;
}
else
{
    order = [[[allItems lastObject] objectIndex] doubleValue] + 1;
}
NSLog(@"Adding after %d items, order = %.2f", [allItems count], order);

RoomItem *p = [NSEntityDescription insertNewObjectForEntityForName:@"RoomItem"
                                                inManagedObjectContext:context];

[p setObjectIndex:[NSNumber numberWithDouble:order]];
[p setDateCreated:[NSDate date]];
[allItems addObject:p];

[self saveChanges];

return p;
}
- (RoomItem *)updateItemWithRoom:(NSString *)room Building:(NSString *)building ObjectIndex:(NSNumber *)objectIndex DateCreated:(NSDate *)dateCreated ImageKey:(NSString *)imageKey BuildingImage:(UIImage *)buildingImage BuildingThumbnail:(UIImage *)buildingThumbnail BuildingThumbnailData:(NSData *)buildingThumbnailData
{
NSError *error = nil;

NSEntityDescription *entity = [NSEntityDescription entityForName:@"RoomItem" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];

int32_t oid = [objectIndex integerValue] - 1;
NSLog(@"objectIndex = %d", oid);

RoomItem *currentRoomItem = [[context executeFetchRequest:request error:&error] objectAtIndex:oid];

//[currentRoomItem setItemEdited:YES];
[currentRoomItem setRoom:room];
[currentRoomItem setBuilding:building];
[currentRoomItem setImageKey:imageKey];
[currentRoomItem setBuildingImage:buildingImage];
[currentRoomItem setBuildingThumbnail:buildingThumbnail];
[currentRoomItem setBuildingThumbnailData:buildingThumbnailData];

[self saveChanges];

return currentRoomItem;
}

最后,setDetailItem和configureView方法:

- (void)setDetailItem:(RoomItem *)detailItem
{
if (_detailItem != detailItem) {
    _detailItem = detailItem;
    [self configureView];
}
}
- (void)configureView
{
if (self.detailItem) {
    [_roomTxt setText:[_detailItem room]];
    [_buildingTxt setText:[_detailItem building]];
    [_dateTxt setText:[self dateCreatedString]];
    [_buildingImageView setImage:[_detailItem buildingImage]];
}
}

这应该作为一个关于花时间阅读核心数据文档或其他任何事情的教训......特别是像我这样的无聊。

再次感谢emrys57的帮助。