Как можно передать NSNumber методу, ожидающему bool? - PullRequest
6 голосов
/ 02 января 2012
[[self.view.window subviews] makeObjectsPerformSelector:@selector(setUserInteractionEnabled:) withObject:[NSNumber numberWithBool:NO]];

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

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

Ответы [ 3 ]

3 голосов
/ 02 января 2012

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

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

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

Легендарный теперь Питер Хоси создал образец базового инструмента здесь , который достаточно странно работает, когдаВы передаете ему двойное число, также как и я сам узнал.

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

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

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

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

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

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

Документы для NSArray состояние:

SetValue: forKey:

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

2 голосов
/ 02 января 2012

Вы не можете передать 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
    
...