Рекомендации по динамическому изменению содержимого базовой модели данных по умолчанию - PullRequest
0 голосов
/ 16 февраля 2011

Я добавил следующее изображение, чтобы лучше проиллюстрировать проблему:

image of window

Привет

Я ищу лучшую отправную точку для непосредственного изменения данных, хранящихся в моей базовой модели данных, - выступая как новичок в этой области. Из моего прочтения я довольно уверен, что не должен касаться моего NSArrayController, который был моим естественным инстинктом, и что я всегда должен заниматься моделью. Это имеет смысл, но поскольку я использовал привязки и основные данные, xcode сгенерировал все для меня, и у меня нет смысла создавать класс с нуля.

Для моей первоначальной задачи у меня есть сущность 'jobs' и NSArrayController. Он имеет атрибут jobTotalHours, который представляет собой строку в формате 00:00:00 и имеет соответствующий столбец «Часы» для каждого задания в NSTableView. Помимо этого, у меня есть кнопка секундомера, которая связана с текстовым полем рядом с ним, отображая время в виде строки 00:00:00. У меня есть рабочий класс, который запускает и останавливает отсчет таймера и отображает его с шагом в часы, минуты и секунды.

Что мне нужно сделать, это сделать так, чтобы таймер добавил время к атрибуту jobTotalHours для текущего задания, выделенного в NSTableView. Отдельное текстовое поле теперь привязано к отображению времени текущего выделенного столбца часов, чтобы эта часть позаботилась. Другими словами, таймер изначально добавлял время к тестовой переменной и отображал его в автономном текстовом поле для целей тестирования. Теперь мне нужно добавить время на любую работу, выделенную в табличном представлении, и мне нужно получить программный доступ к модели, не зная, какой шаг предпринять первым.

Заранее спасибо за любой совет. Я включу класс таймера ниже, если он будет полезен. Я уверен, что это грубо и плохо, но это работает:

timerController.h:

#import <Cocoa/Cocoa.h>
BOOL timerStarted;
int timerCount;
int timerSeconds;
int timerMinutes;
int timerHours;
NSString *timerString;
NSString *timerFieldSeconds;
NSString *timerFieldMinutes;
NSString *timerFieldHours;

@interface timerController : NSObject <NSApplicationDelegate> {
    NSWindow *window;
    NSTimer *timerNoOne;
    IBOutlet NSCell *timerOneOutputLabel;
    IBOutlet id timerClockField;
}
-(IBAction)toggleTimerClock:(id)sender;
@property (assign) IBOutlet NSWindow *window;

@end

timerController.m:

#import "timerController.h"


@implementation timerController
-(IBAction)toggleTimerClock:(id)sender
{
    if (timerStarted==FALSE) {
        timerStarted = TRUE;
    } else {
        timerStarted = FALSE;
    }
}

@synthesize window;


- (void) awakeFromNib {
    // clear timer 
    [timerClockField setStringValue:@"00:00:00"];
    // initialize timer to count each second
    timerNoOne = [NSTimer scheduledTimerWithTimeInterval:1 
                            target:self 
                            selector:@selector(updateTimerNoOne:) 
                            userInfo:nil 
                            repeats:YES];   

}


- (void) updateTimerNoOne:(NSTimer *) timer {
    if (timerStarted==FALSE) {
        // do nothing. Timer is switched off.
    } else {
        timerCount = timerCount + 1;
        timerSeconds = fmod(timerCount, 60);
        timerMinutes = floor(timerCount / 60);
        timerHours = floor(timerCount / 3600);

        if (timerSeconds < 10) { // add a leading 0 for formatting reasons.
            timerFieldSeconds = [NSString stringWithFormat:@"0%d",timerSeconds];
        } else {
            timerFieldSeconds = [NSString stringWithFormat:@"%d",timerSeconds];
        }

        if (timerMinutes < 10) {
            timerFieldMinutes = [NSString stringWithFormat:@"0%d",timerMinutes];
        } else {
            timerFieldMinutes = [NSString stringWithFormat:@"%d",timerMinutes];
        }

        if (timerHours < 10) {
            timerFieldHours = [NSString stringWithFormat:@"0%d",timerHours];
        } else {
            timerFieldHours = [NSString stringWithFormat:@"%d",timerHours];
        }

        NSString *timerString = [NSString stringWithFormat:@"%@:%@:%@",timerFieldHours,timerFieldMinutes,timerFieldSeconds];
        //[timerClockField setStringValue:timerString];

    }
}
@end

Обновление:

Прочитав еще немного, я задаюсь вопросом, лучше ли мне обновлять строку в самом текстовом ячейке каждую секунду изменения таймера, а затем фиксировать изменения в модели только после окончания таймера (например, часы были остановлен). Раньше я думал о сохранении строки jobTotalHours модели секунду за секундой, так как это напрямую изменяло модель и избегало контроллеров, что я считал рекомендуемым маршрутом.

Обновление:

У меня был настроен подкласс для NSTableView и NSArrayController. Я смог использовать их, чтобы обнаружить изменения выбора строк в таблице и распечатать их на консоли. Подкласс был назван:

@interface modelUtilController : NSObject

Который отлично выполнил вышеуказанные задачи. Теперь я хотел получить выход к NSManagedObject, чтобы я мог напрямую манипулировать активами в нем, сохраняя при этом выходы к NSTableView для обнаружения изменений в выборе строк. Я прочитал, что подкласс должен быть

@interface modelUtilController : NSManagedObject

который я изменил и включил выход в модель данных. Это сбивает исходное обнаружение изменений в выборе строк, поэтому я сейчас что-то делаю не так. Возможно, я должен разделить подкласс на 2?

Обновление: возможно завершено

Хорошо, я думаю, что решил это через 3 дня. Насколько я вижу, это работает, но я еще не использовал его полностью. По сути, я создал отдельную функцию, которую я вызываю из таймера каждую секунду:

void amendTotalHours(id anObject)

Эта функция использует мои задания NSArrayController, а затем находит текущее значение в столбце часов, используя:

NSArray *selectedObjectsArray = [anObject selectedObjects];
NSManagedObjectModel *firstSelectedObject = [selectedObjectsArray objectAtIndex:0];
NSString *readCurrentTime = [firstSelectedObject valueForKey:@"jobTotalHours"];

Затем я преобразую строку времени, отформатированную в 00:00:00, в целое число от общего числа секунд. Я добавляю по одному для каждого вызова из таймера, а затем конвертирую секунды обратно в строку в формате 00:00:00. Наконец, я отправляю это обратно в NSArrayController, используя:

[firstSelectedObject setValue:[NSString stringWithFormat:@"%@", timeValue] forKey:@"jobTotalHours"];

И плачь (может быть, временный) с облегчением.

1 Ответ

0 голосов
/ 18 февраля 2011

Хорошо, я думаю, что решил это через 3 дня.Насколько я вижу, это работает, но я еще не использовал его полностью.По сути, я создал отдельную функцию, которую я вызываю из своего таймера раз в секунду:

void amendTotalHours(id anObject)

Эта функция использует мои задания NSArrayController, а затем находит текущее значение в столбце часов, используя:

NSArray *selectedObjectsArray = [anObject selectedObjects];
NSManagedObjectModel *firstSelectedObject = [selectedObjectsArray objectAtIndex:0];
NSString *readCurrentTime = [firstSelectedObject valueForKey:@"jobTotalHours"];

Затем я преобразую строку времени в формате 00:00:00 в целое число от общего числа секунд.Я добавляю по одному для каждого вызова из таймера, а затем конвертирую секунды обратно в строку в формате 00:00:00.Наконец, я отправляю это обратно в NSArrayController, используя:

[firstSelectedObject setValue:[NSString stringWithFormat:@"%@", timeValue] forKey:@"jobTotalHours"];

И вздыхаю (может быть, временно) с облегчением.

...