1

このメソッドがスキップされないようにするために、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];
}

RoomList:sharedStoreから、詳細ビューコントローラに必要なすべてのものを渡す必要があるtableView:didSelectRowAtIndexPathメソッドを次に示します。

- (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図です(左から右、上から下に読み取ります): ここに画像の説明を入力してください

4

2 に答える 2

1

セッターが呼び出されないのは非常に奇妙です。私は線を取るだろう

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

そして、ブレークポイントに到達したら、コンパイル済みのアセンブラを 1 ステップ実行して、それがどこにあるのかを調べます。そのための指示がXcode Debugger にあります - how to single step at level of CPU instructions - 具体的には数週間前の Max MacLeod からの回答です。

これは実際には答えではないので、別のコメントとして書いたはずですが、長すぎます!

于 2012-11-28T21:58:30.677 に答える
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 ファイルを再構築する必要がありました。最初は、作成機能と更新機能を 1 つのメソッドに結合しようとしました。MVC で作成し、DVC で更新するとうまくいきません。

だから私は2つを分割しました:

- (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に再び感謝します。

于 2012-11-29T18:42:29.223 に答える