Почему свойство только для чтения все еще позволяет писать с KVC

Компиляторы в целом очень умны.

то, Что необходимо рассмотреть, - то, что они должны составлять каждый возможно исключение или ситуация, где оптимизация или рефакторинг кода могли вызвать нежелательные побочные эффекты.

Вещи как, потоковые программы, искажение указателя, динамично связали код, и побочные эффекты (системное выделение вызовов/памяти) и т.д. делают официально доказательство рефакторинга очень трудным.

Даже при том, что Ваш пример прост, все еще может быть трудными ситуациями для рассмотрения.

Что касается Вашего аргумента StringBuilder, который НЕ является заданием компиляторов для выбора который структуры данных использовать для Вас.

, Если Вы хотите более мощное перемещение оптимизаций на язык более со строгим контролем типов как Фортран или haskell, где компиляторам дают намного больше информации для работы с.

Большинство курсов обучающие компиляторы/оптимизация (даже acedemically) дают смысл оценки о том, как, делая gerneral официально оптимизации продуховки вместо того, чтобы взломать конкретные случаи являются очень трудной проблемой.

5
задан nevan king 1 October 2009 в 09:05
поделиться

3 ответа

Способ Maven "запустить" другую сборку - это определить многомодульную сборку . В родительском проекте pom можно указать модули, которые будут построены с использованием стандартного жизненного цикла. Таким образом, запуск mvn install на родительском элементе будет означать, что каждый модуль будет построен по очереди.

Родитель определен с помощью pom packagin и будет иметь такое объявление модулей:

@interface AppController : NSObject
{
        int fido;
}

@property (readonly, assign) int fido;
@end

import "AppController.h"

@implementation AppController
@synthesize fido;
...
@end

На этом этапе вы объявили, что AppController имеет метод -fido , и вы синтезировали этот метод. Не существует метода -setFido: . Итак, почему следующая «работа»?

- (id)init
{
        if (self=[super init]) {
            [self setValue:[NSNumber numberWithInt:5] forKey:@"fido"];
            NSNumber *n = [self valueForKey:@"fido"];
            NSLog(@"fido = %@", n);
        }
        return self;
}

(Кстати: я исправил ваш -init для реализации правильного шаблона)

Это работает, потому что KVC следует эвристике для установки или получения значения. Вызов -setValue: forKey: сначала ищет -setFoo: . Если не найден, он затем ищет переменную экземпляра foo и устанавливает ее напрямую.

Обратите внимание, что если вы измените переменную экземпляра fido на _fido , набор будет работать, но valueForKey вернет 0 при вызове синтезированного метода (поскольку я использую 64-разрядную версию, @synthesize синтезирует переменную экземпляра fido . Я знаю, что сбивает с толку.)

Если бы вы изменили имя своего ivar на bar , а затем использовали @synthesize foo = bar; , код не работал бы во время выполнения .

Вы увидите:

2009-10-01 08:59:58.081 dfkjdfkjfjkfd[24099:903] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AppController 0x20000e700> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key fido.'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00007fff85b055a4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff85c5a0f3 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff85b5caf9 -[NSException raise] + 9
    3   Foundation                          0x00007fff814e14f5 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 434
(
    0   CoreFoundation                      0x00007fff85b055a4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff85c5a0f3 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff85b5caf9 -[NSException raise] + 9
    3   Foundation                          0x00007fff814e14f5 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 434
    4   dfkjdfkjfjkfd                       0x0000000100000d96 -[AppController init] + 130
16
ответ дан 18 December 2019 в 09:08
поделиться

Наличие свойства readonly означает, что компилятор не сгенерирует вам сеттер для этого свойства. По-прежнему разрешено писать на него через KVO / KVC.

1
ответ дан 18 December 2019 в 09:08
поделиться

Директивы компилятора @property и @synthesize - это просто сокращенные способы создания методов для получения и установки рассматриваемой переменной.

Созданный метод установки называется setFido: , а метод получения - просто fido .

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

(Надеюсь, у меня все правильно. Удачи!)

1
ответ дан 18 December 2019 в 09:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: