Как можно передать NSNumber методу, ожидающему bool?

[[self.view.window subviews] makeObjectsPerformSelector:@selector(setUserInteractionEnabled:) withObject:[NSNumber numberWithBool:NO]];

Я видел этот код в ответе на другой вопрос ( Как отключить сенсорный ввод для всех представлений, кроме самого верхнего?), И он удивил меня, когда он работал, так как setUserInteractionEnabled: ожидает, что BOOL (который не является объектом target-c, не может быть передан в performSelector:withObject: методы типа).

Где документация, в которой говорится, что передача NSNumber в порядке? Работает ли он для всех методов или нужна специальная реализация? И это работает только с BOOL, или это может быть сделано с такими типами, как int?

3 ответа

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

Это не работает. Я пробовал это в проекте iOS, свойство userInteractionEnabled не влияет на отправку performSelector:withObject:, Это соответствует документации для NSObject, которая гласит:

aSelector должен идентифицировать метод, который принимает один аргумент типа id. Для методов с другими типами аргументов и возвращаемых значений используйте NSInvocation.

Теперь легендарный Peter Hosey построил здесь примерный фундаментный инструмент, который достаточно странно работает, когда вы передаете ему двойной дубль, а также, как я сам узнал, поплавок.

Чтобы добавить любопытство к любопытству, это не работает в проекте iOS (double или float).

В целом, я думаю, что мы можем сказать следующее:

  • Если это когда-либо работает, это работает случайно, и на него нельзя полагаться
  • Принятый или отклоненный ответ о переполнении стека не обязательно является правильным

Я думаю, что вы уже пришли к выводу, что это не работает.

@senojsitruc предлагает несколько разных способов сделать это, но упускает из виду самое простое решение

[self.view.window.subviews setValue:[NSNumber numberWithBool:NO] forKey:@"userInteractionEnabled"]; 

Документы для NSArray заявляют:

SetValue:forKey:

Вызывает setValue:forKey: для каждого элемента массива, используя указанное значение и ключ.

Вы не можете передать NSNumber в качестве объекта, и он будет выглядеть как BOOL на другом конце, как этот. Тем не менее, есть некоторые обходные пути.

  1. Используйте NSInvocation. Вам нужно создать категорию NSArray, которая использует NSInvocation. Это немного грязно.

  2. Создайте категорию UIView с помощью функции setUserInteractionEnabled:-like (с похожим именем?), Которая работает с NSNumber, который затем вызывает setUserInteractionEnabled: со значением BOOL NSNumber. Что-то вроде:

    @implementation UIView (Additions)
    - (BOOL)setUserInteractionEnabled2:(NSNumber *)aBool
    {
      self.userInteractionEnabled = [aBool boolValue];
    }
    @end
    
Другие вопросы по тегам