Слишком много аргументов для вызова функции, ожидается 0, есть 3
это компилирует / отлично работает с Xcode 5, но вызывает ошибку компиляции с Xcode 6 Beta 4:
objc_msgSend(anItem.callback_object,
NSSelectorFromString(anItem.selector), dict);
Это 3-й партии компонентов, поэтому, хотя у меня есть исходный код, это не совсем мой код, и я не решаюсь его сильно изменить (несмотря на мое личное мнение о " wtf, почему они используют objc_msgSend
??').
Изображение с возможно полезной детализацией (ошибка в браузере ошибок):
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
использование Cocoapods0.36.beta.2
. Я сообщил о проблеме CocoaPods. "Обходной путь" с помощью CocoaPods0.35
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 не объявлена, но каким-то волшебным образом он показывает другую ошибку. Другими словами, если у вас есть блок, вы можете поместить любые параметры при его вызове, даже несуществующие переменные.