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


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

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

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

Изображение с возможно полезной детализацией (ошибка в браузере ошибок):

11 54

11 ответов:

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

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

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

просто чтобы сэкономить на просмотре видео 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);

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

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

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

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

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

enter image description here

Maciej Swic прав.Это вызвано в стручках после обновления Cocoapods до 0.36.бета.2. Я нашел простой обходной путь по типу casting objc_msgSend:

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

Я получал эту ошибку с QuickDialog. После ответа james_alvarez, но для AppCode перейдите к Project Settings, затем нажмите QuickDialog в разделе Project/Shared Settings прокрутите вниз до ENABLE_STRICT_OBJC_MSGSEND и введите NO для отладки и выпуска.

вы также можете отключить это с помощью post install hook:

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
#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);
}

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

я отредактировал код в 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

этот блок кода, воспроизводящий ошибку:

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

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