Как переопределить представление NSError, когда задействованы привязки?

Одна вещь, с которой у меня всегда были проблемы в Cocoa Bindings, — это представление ошибок, например, когда пользователь вводит неправильное значение в текстовое поле с прикрепленным средством форматирования. Обычно я бы переопределял willPresentError: где-то в цепочке респондентов, но моя проблема заключается в том, что объекты NSError, созданные системой Bindings, не содержат достаточно информации, чтобы я мог сказать, что не удалось, или если это даже ошибка, которую я заинтересован в настройке. Я мог бы полностью удалить привязки из уравнения и создать свои собственные ошибки при возникновении проблем с проверкой, но я чувствую, что таким образом выбрасываю некоторые полезные вещи.

Я смог обойти это, реализовав методы делегата NSControl и сохранив элемент управления, который не удалось выполнить, в переменной экземпляра в моем контроллере представления. Если он не равен нулю к тому времени, когда willPresentError: накатывает, я знаю, что не удалось проверить.

- (BOOL)control:(NSControl *)control didFailToFormatString:(NSString *)string errorDescription:(NSString *)error;
{
    _errorSender = [control retain];
    return NO;
}

- (NSError *)willPresentError:(NSError *)error;
{
    if ( _errorSender != nil )
    {
        NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:[error userInfo]];
        NSString *help = NSLocalizedString( @"Why are you always messing up? You are a terrible person.", @"" );

        [_errorSender release];
        _errorSender = nil;
        [userInfo setObject:help forKey:NSLocalizedRecoverySuggestionErrorKey];

        return [NSError errorWithDomain:[error domain] code:[error code] userInfo:userInfo];
    }

    return [super willPresentError:error];
}

Это работает, когда меняется первый ответчик, но не когда я вызываю commitEditing на контроллере представления, поэтому для меня это полезно лишь частично.

Единственный другой вариант, который я вижу, - это исключить NSFormatter из уравнения и использовать validateValue:forKey:error: в моих управляемых объектах Core Data для обработки проверки. Это не имеет для меня такого большого смысла, как использование средства форматирования, но, по крайней мере, у меня будет полный контроль над объектом NSError.

Я чувствую, что должен что-то упустить, чтобы возникло такое отключение при обработке ошибок. Какие-либо предложения?


person Marc Charbonneau    schedule 23.05.2009    source источник


Ответы (1)


Я мог бы полностью удалить привязки из уравнения и создать свои собственные ошибки при возникновении проблем с проверкой, но я чувствую, что таким образом выбрасываю некоторые полезные вещи.

Вы можете использовать NSUnderlyingErrorKey, чтобы обернуть одну ошибку (объект для этого ключа) в другую ошибку (ту, чье userInfo содержит этот ключ).

Единственный другой вариант, который я вижу, - это исключить NSFormatter из уравнения и использовать validateValue: forKey: error: в моих управляемых объектах Core Data для обработки проверки. Это не имеет для меня такого большого смысла, как использование средства форматирования, но, по крайней мере, у меня будет полный контроль над объектом NSError.

Это два отдельных уровня, и они не исключают друг друга. Проверка средства форматирования выполняется на уровне представления; проверка значения ключа (в данном случае в ваших управляемых объектах) находится на уровне модели.

Если рассматриваемая проверка должна происходить на уровне представления, создайте подкласс вашего класса NSFormatter (если вы еще этого не сделали) и реализуйте getObjectValue:forString:errorDescription:, чтобы вернуть более конкретное описание ошибки. (Я понятия не имею, действительно ли Bindings использует это описание ошибки. Вы должны проверить.)

Если проверка должна выполняться на уровне модели, реализуйте validate<Key>:error: (версия validateValue:forKey:error: с одним свойством) в своем подклассе NSManagedObject.

Если некоторые из ограничений находятся на уровне модели, а другие — на уровне представления, сделайте и то, и другое. Вы можете реализовать некоторые проверки в средстве форматирования и другие проверки в модели, если это имеет смысл для вашего приложения и ваших проверок.

person Peter Hosey    schedule 23.05.2009
comment
Я создаю подкласс NSFormatter, и хотя привязки действительно используют сообщение об ошибке NSString, я предоставляю окончательный NSAlert, который все еще довольно голый (я хотел бы как минимум добавить предложение по восстановлению ошибки). Проверка, которую я делаю, кажется, лучше подходит для моих подклассов NSFormatter, поэтому я не решаюсь реализовать проверку значения ключа в моей модели. Я бы закончил тем, что выполнял всевозможный синтаксический анализ строк, который не имеет ничего общего с моделью данных, просто чтобы иметь возможность настроить внешнее сообщение об ошибке, когда что-то пойдет не так. - person Marc Charbonneau; 24.05.2009