Obj C и makeObjectsPerformSelector — я что-то упускаю из виду?

#ios #objective-c #xcode

#iOS #objective-c #xcode

Вопрос:

будучи все еще новичком в obj-c, я поиграл с методом makeObjectsPerformSelector.

У меня есть два массива, содержащих UISteppers и UITextFields соответственно:

 _stepper = [NSArray arrayWithObjects:
           _stepMa, _stepMafree, _stepDe,   _stepDefree,   _stepFl, _stepFlfree,
           _stepEn, _stepEnfree, _stepEnBl, _stepEnBlfree, _stepVo, _stepVofree,
           _stepVe, _stepVefree, _stepIn,   _stepInfree,   _stepOt, _stepOtfree,
           _stepIn170, _stepIn170free, _stepZy, _stepZyfree,
           nil];

_fields = [NSArray arrayWithObjects:
           _MaFeld, _MaFeldfree, _DeFeld,   _DeFeldfree,   _FlFeld, _FlFeldfree,
           _EnFeld, _EnFeldfree, _EnBlFeld, _EnBlFeldfree, _VoFeld, _VoFeldfree,
           _VeFeld, _VeFeldfree, _InFeld,   _InFeldfree,   _OtFeld, _OtFeldfree,
           _InFeld170, _InFeld170free, _ZyFeld, _ZyFeldfree,
           nil];
  

Каким-то методом я хочу их сбросить:

 - (void) resetFields
{
    [_stepper enumerateObjectsUsingBlock: ^(UIStepper* stepper, NSUInteger idx, BOOL *stop)
     {
         stepper.value = 0;
     }];

    [_fields enumerateObjectsUsingBlock: ^(UITextField* field, NSUInteger idx, BOOL *stop)
     {
         field.text = @"0";
     }];
}
  

который работает так, как ожидалось.

пытаясь немного сократить этот код, я попытал счастья с упомянутым методом:

 - (void) resetFields
{
    [_stepper makeObjectsPerformSelector:@selector(value) withObject:0];
    [_fields  makeObjectsPerformSelector:@selector(text)  withObject:@"0"];
}
  

что не возымело никакого эффекта… Я предполагаю, что есть что-то, чего я не учел, но что?

Спасибо!

Комментарии:

1. установщик — это селектор, который вам нужно выполнить, например, –setText: или –setValue: , но это –makeObjectsPerformSelector:withObject: не будет работать с –setValue: , поскольку ожидаемое значение является примитивом , а не объектом

2. Аааа! Не знал об этом. Спасибо!

Ответ №1:

Чтобы обойти проблему, связанную с тем, что int является типом C, а не объектом, используйте KVC (кодирование ключ-значение). Если вы вызываете setValue:forKey: для объекта NSArray, метод setValue:forKey: вызывается для каждого из объектов массива. И в качестве бонуса, KVC управляет всеми примитивными элементами.

 [_stepper setValue:@0 forKey:@"value"];
[_fields setValue:@"0" forKey:@"text"];
  

Ответ №2:

performSelector вызовы (все их виды) могут принимать только объекты Objective-C (те, которые могут быть представлены id типом). Типы C, такие как double , BOOL int и т.д. не будет работать, поэтому вы не сможете настроить value таким образом, если не измените его тип на NSNumber* .

Для настройки text свойства вам нужно использовать setText: selector; text является средством получения. Поскольку этот тип свойства относится к классу Objective-C NSString , performSelector будет работать.

Комментарии:

1. Ага, спасибо за подсказку — глупый я; просто предположил, а не подумал (потому что .value также работал для установки значения UIStepper).