NSInvocation для макетов?

print("if u wanna quit inputting number, press '-1'")
print("="*60)

a=[]

while True:
    i = int(input())
    if i==-1:
        break
    else:
        a.append(i)

def avrg(a):
    return sum(a)/len(a)

b=avrg(a)
print(b)

Пользовательский ввод из функции input() всегда имеет тип str, поэтому вам необходимо преобразовать его в int перед сравнением if i==-1. В цикле while он продолжает потреблять пользовательский ввод, пока пользователь не введет -1. Сумма списка может быть просто вычислена встроенной функцией sum.

138
задан Chris Hanson 24 November 2008 в 04:20
поделиться

3 ответа

Согласно ссылке класса Apple NSInvocation:

NSInvocation сообщение Objective C, представленное статичным, то есть, это - действие, превратился в объект.

И, в немного большем количестве деталей:

Понятие сообщений является центральным к объективной-c философии. Любое время Вы называете метод или получаете доступ к переменной некоторого объекта, Вы отправляете ему сообщение. NSInvocation пригождается, когда Вы хотите отправить сообщение в объект в другом моменте времени или отправить то же сообщение несколько раз. NSInvocation позволяет Вам описывать сообщение, которое Вы собираетесь отправить, и затем вызвать его (на самом деле отправляют его в целевой объект), позже.


Например, скажем, Вы хотите добавить строку к массиву. Вы обычно отправляли бы addObject: сообщение следующим образом:

[myArray addObject:myString];

Теперь, скажем, Вы хотите использовать NSInvocation отправить это сообщение в некотором другом моменте времени:

Во-первых, Вы подготовились бы NSInvocation объект для использования с NSMutableArray addObject: селектор:

NSMethodSignature * mySignature = [NSMutableArray
    instanceMethodSignatureForSelector:@selector(addObject:)];
NSInvocation * myInvocation = [NSInvocation
    invocationWithMethodSignature:mySignature];

Затем, Вы указали бы который объект отправить сообщение в:

[myInvocation setTarget:myArray];

Укажите сообщение, которое Вы хотите отправить в тот объект:

[myInvocation setSelector:@selector(addObject:)];

И заполните любые аргументы в пользу того метода:

[myInvocation setArgument:&myString atIndex:2];

Обратите внимание, что объектные аргументы должны быть переданы указателем. Спасибо Ryan McCuaig для указания, что, и дополнительную информацию см. в документации Apple.

На данном этапе myInvocation полный объект, описывая сообщение, которое может быть отправлено. Для фактической отправки сообщения Вы звонили бы:

[myInvocation invoke];

Этот заключительный шаг заставит сообщение быть отправленным, по существу выполняясь [myArray addObject:myString];.

Думайте о нем как отправка электронного письма. Вы открываете новое электронное письмо (NSInvocation объект), заполните адрес человека (объект), в кого Вы хотите отправить его, введите в сообщении для получателя (укажите a selector и аргументы), и затем нажимают, "отправляют" (вызов invoke).

Посмотрите Используя NSInvocation для получения дополнительной информации. Посмотрите Используя NSInvocation, если вышеупомянутое не работает.


NSUndoManager использование NSInvocation объекты так, чтобы это могло инвертировать команды. По существу то, что Вы делаете, создает NSInvocation объект сказать: "Эй, если Вы хотите отменить то, что я просто сделал, отправьте это сообщение в тот объект с этими аргументами". Вы даете NSInvocation возразите против NSUndoManager, и это добавляет что объект к массиву невозможных действий. Если вызовы пользователя "Отменяют", NSUndoManager просто ищет новое действие в массиве и вызывает сохраненный NSInvocation объект выполнить необходимое действие.

Дополнительную информацию см. в Регистрирующихся Операциях Отмены.

280
ответ дан 23 November 2019 в 23:26
поделиться

Вы можете попробовать просто использовать здесь библиотеку, которая гораздо приятнее: http://cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html

5
ответ дан 23 November 2019 в 23:26
поделиться

Вот простой пример NSInvocation в действии:

- (void)hello:(NSString *)hello world:(NSString *)world
{
    NSLog(@"%@ %@!", hello, world);

    NSMethodSignature *signature  = [self methodSignatureForSelector:_cmd];
    NSInvocation      *invocation = [NSInvocation invocationWithMethodSignature:signature];

    [invocation setTarget:self];                    // index 0 (hidden)
    [invocation setSelector:_cmd];                  // index 1 (hidden)
    [invocation setArgument:&hello atIndex:2];      // index 2
    [invocation setArgument:&world atIndex:3];      // index 3

    // NSTimer's always retain invocation arguments due to their firing delay. Release will occur when the timer invalidates itself.
    [NSTimer scheduledTimerWithTimeInterval:1 invocation:invocation repeats:NO];
}

При вызове - [self hello:@"Hello" world:@"world"]; - метод:

  • Выведет "Hello world!"
  • Создаст для себя NSMethodSignature.
  • Создаст и заполнит NSInvocation, вызывая себя.
  • Передадим NSInvocation в NSTimer
  • Таймер сработает (приблизительно) через 1 секунду, что приведет к повторному вызову метода с исходными аргументами.
  • Повторите.

В итоге вы получите такую распечатку:

2010-07-11 17:48:45.262 Your App[2523:a0f] Hello world!
2010-07-11 17:48:46.266 Your App[2523:a0f] Hello world!
2010-07-11 17:48:47.266 Your App[2523:a0f] Hello world!
2010-07-11 17:48:48.267 Your App[2523:a0f] Hello world!
2010-07-11 17:48:49.268 Your App[2523:a0f] Hello world!
2010-07-11 17:48:50.268 Your App[2523:a0f] Hello world!
2010-07-11 17:48:51.269 Your App[2523:a0f] Hello world!
...

Конечно, целевой объект self должен продолжать существовать, чтобы NSTimer мог послать ему NSInvocation. Например, объект Singleton или AppDelegate, который существует в течение всего времени работы приложения.


UPDATE:

Как отмечалось выше, когда вы передаете NSInvocation в качестве аргумента в NSTimer, NSTimer автоматически сохраняет все аргументы NSInvocation.

Если вы не передаете NSInvocation в качестве аргумента в NSTimer, но планируете, что он будет существовать некоторое время, вы должны вызвать его метод -retainArguments. В противном случае его аргументы могут быть удалены до вызова, что в конечном итоге приведет к аварийному завершению вашего кода. Вот как это сделать:

NSMethodSignature *signature  = ...;
NSInvocation      *invocation = [NSInvocation invocationWithMethodSignature:signature];
id                arg1        = ...;
id                arg2        = ...;

[invocation setTarget:...];
[invocation setSelector:...];
[invocation setArgument:&arg1 atIndex:2];
[invocation setArgument:&arg2 atIndex:3];

[invocation retainArguments];  // If you do not call this, arg1 and arg2 might be deallocated.

[self someMethodThatInvokesYourInvocationEventually:invocation];
47
ответ дан 23 November 2019 в 23:26
поделиться