Слишком много аргументов для вызова функции, ожидаемого 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 не объявлен, но каким-то волшебным образом он показывает другую ошибку. Другими словами, если у вас есть блок, вы можете поместить любые параметры при вызове, даже несуществующие переменные.