Слишком много аргументов для вызова функции, ожидаемого 0, имеют 3

Это компилирует/отлично работает с Xcode 5, но вызывает ошибку компиляции с Xcode 6 Beta 4:

objc_msgSend(anItem.callback_object,
NSSelectorFromString(anItem.selector), dict);

Это сторонний компонент, поэтому, хотя у меня есть исходный код, это не совсем мой код, и я не решаюсь его сильно изменить (несмотря на мое личное мнение о wtf, почему они используют objc_msgSend? ").

Изображение с полезной деталью (ошибка в браузере ошибок): enter image description here

Ответ 1

Я нашел ответ, и он на Сессии 417 с 2014 года WWDC "Что нового в LLVM". Если вы найдете этот код в сторонней библиотеке, такой как Apsalar, обновление до последней версии исправляет его (возможно, потому, что он не распространяется как lib, ha). Пример приведения этих вызовов см. В библиотеке THObserversAndBinders - я использую его и заметил, что автор обновил код, например здесь:

https://github.com/th-in-gs/THObserversAndBinders/blob/master/THObserversAndBinders/THObserver.m

Ответ 2

Если вы считаете, что делать это раздражает и бессмысленно, вы можете отключить проверку в настройках сборки, установив "Включить строгую проверку вызовов objc_msgSend" на no

Ответ 3

Это также может быть вызвано запуском pod install с использованием Cocoapods 0.36.beta.2. Я сообщил об этой проблеме CocoaPods. "Обходной путь" с использованием CocoaPods 0.35

Ответ 4

Просто чтобы посмотреть видео WWDC, ответ вам нужен сильный тип objc_msgSend для компилятора для его сборки:

typedef void (*send_type)(void*, SEL, void*);
send_type func = (send_type)objc_msgSend;
func(anItem.callback_object, NSSelectorFromString(anItem.selector), dict);

Вот еще один пример при непосредственном вызове методов экземпляра, например:

IMP methodInstance = [SomeClass instanceMethodForSelector:someSelector];
methodInstance(self, someSelector, someArgument);

Используйте сильный тип для методаInstance, чтобы сделать компилятор LLVM счастливым:

typedef void (*send_type)(void*, SEL, void*);
send_type methodInstance = (send_type)[SomeClass instanceMethodForSelector:someSelector];
methodInstance(self, someSelector, someArgument);

Не забудьте указать типы возвратов и аргументов send_type в соответствии с вашими конкретными потребностями.

Ответ 5

Maciej Swic прав. Это вызвано в Pods после обновления Cocoapods до 0,36. 2. Я нашел простой способ обхода типа objc_msgSend:

id (*typed_msgSend)(id, SEL) = (void *)objc_msgSend;
id<MyProtocol> obJ = typed_msgSend(controller, @selector(myselector));

Ответ 6

Я получал эту ошибку с помощью QuickDialog. После ответа james_alvarez, но для AppCode перейдите к Project Settings, затем нажмите QuickDialog в разделе "Параметры проекта/общего доступа", прокрутите вниз до ENABLE_STRICT_OBJC_MSGSEND и введите "НЕТ" для "Отладка и выпуск".

Ответ 7

Настройка Enable strict checking of objc_msgSend Calls на NO, решила мою проблему. Ниже приведен скриншот

введите описание изображения здесь

Ответ 8

Вы также можете отключить это с помощью установочного крючка:

post_install do |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['ENABLE_STRICT_OBJC_MSGSEND'] = 'NO'
        end
    end
end

Ответ 9

#include <objc/message.h>

void foo(void *object) {
  typedef void (*send_type)(void *, SEL, int);
  send_type func = (send_type)objc_msgSend;
  func(object, sel_getUid("foo:"), 5);
}

Ответ 10

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

Я редактировал код в ActionSheetPicker в моем проекте, что вызывало у меня такую ​​же проблему, как это -

- (void)notifyTarget:(id)target didSucceedWithAction:(SEL)action origin:(id)origin {
    if ([target respondsToSelector:action]) {
        ((id (*)(id, SEL, NSDate *, id))objc_msgSend)(target, action, self.selectedDate, origin);
        return;
    } else if (nil != self.onActionSheetDone) {
        self.onActionSheetDone(self, self.selectedDate, origin);
        return;
    }

    NSAssert(NO, @"Invalid target/action ( %s / %s ) combination used for ActionSheetPicker", object_getClassName(target), (char *)action);
}

Итак, посмотрите на изменение, которое имеет часть objc_msgSend, по сравнению с вашим текущим кодом. Идея состоит в том, чтобы включить тип параметров, которые вы передаете, в objc_msgSend

Ответ 11

Этот блок кода воспроизводит ошибку:

- (void)reportSuccess:(void(^)(void))success
{
    success(what_is_this);
}

Угадайте, где ошибка? Конечно, what_is_this не объявлен, но каким-то волшебным образом он показывает другую ошибку. Другими словами, если у вас есть блок, вы можете поместить любые параметры при вызове, даже несуществующие переменные.