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

Привет
Я ищу лучшую отправную точку для непосредственного изменения данных, хранящихся в моей базовой модели данных, - выступая как новичок в этой области. Из моего прочтения я довольно уверен, что не должен касаться моего 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"];
И плачь (может быть, временный) с облегчением.