我收到此错误。我承认我对使用Xcode一无所知。我收到了这段代码,并被告知它会起作用。除了两个错误之外,一切都很好。具体的代码段是:
objc_msgSend(obj, legacySelector, arguments, dict);
和
objc_msgSend(obj, normalSelector, command);
完整的代码如下:
#include <objc/message.h>
#import "CDV.h"
#import "CDVCommandQueue.h"
#import "CDVViewController.h"
@implementation CDVCommandQueue
@synthesize currentlyExecuting = _currentlyExecuting;
- (id)initWithViewController:(CDVViewController*)viewController
{
self = [super init];
if (self != nil) {
_viewController = viewController;
_queue = [[NSMutableArray alloc] init];
}
return self;
}
- (void)resetRequestId
{
_lastCommandQueueFlushRequestId = 0;
}
- (void)enqueCommandBatch:(NSString*)batchJSON
{
if ([batchJSON length] > 0) {
[_queue addObject:batchJSON];
[self executePending];
}
}
- (void)maybeFetchCommandsFromJs:(NSNumber*)requestId
{
// Use the request ID to determine if we've already flushed for this request.
// This is required only because the NSURLProtocol enqueues the same request
// multiple times.
if ([requestId integerValue] > _lastCommandQueueFlushRequestId) {
_lastCommandQueueFlushRequestId = [requestId integerValue];
[self fetchCommandsFromJs];
}
}
- (void)fetchCommandsFromJs
{
// Grab all the queued commands from the JS side.
NSString* queuedCommandsJSON = [_viewController.webView stringByEvaluatingJavaScriptFromString:
@"cordova.require('cordova/exec').nativeFetchMessages()"];
[self enqueCommandBatch:queuedCommandsJSON];
}
- (void)executePending
{
// Make us re-entrant-safe.
if (_currentlyExecuting) {
return;
}
@try {
_currentlyExecuting = YES;
for (NSUInteger i = 0; i < [_queue count]; ++i) {
// Parse the returned JSON array.
NSArray* commandBatch = [[_queue objectAtIndex:i] cdvjk_mutableObjectFromJSONString];
// Iterate over and execute all of the commands.
for (NSArray* jsonEntry in commandBatch) {
CDVInvokedUrlCommand* command = [CDVInvokedUrlCommand commandFromJson:jsonEntry];
if (![_viewController execute:command]) {
#ifdef DEBUG
NSString* commandJson = [jsonEntry cdvjk_JSONString];
static NSUInteger maxLogLength = 1024;
NSString* commandString = ([commandJson length] > maxLogLength) ?
[NSString stringWithFormat:@"%@[...]", [commandJson substringToIndex:maxLogLength]] :
commandJson;
DLog(@"FAILED pluginJSON = %@", commandString);
#endif
}
}
}
[_queue removeAllObjects];
} @finally
{
_currentlyExecuting = NO;
}
}
- (BOOL)execute:(CDVInvokedUrlCommand*)command
{
if ((command.className == nil) || (command.methodName == nil)) {
NSLog(@"ERROR: Classname and/or methodName not found for command.");
return NO;
}
// Fetch an instance of this class
CDVPlugin* obj = [_viewController getCommandInstance:command.className];
if (!([obj isKindOfClass:[CDVPlugin class]])) { // still allow deprecated class, until 1.0 release
NSLog(@"ERROR: Plugin '%@' not found, or is not a CDVPlugin. Check your plugin mapping in Cordova.plist.", command.className);
return NO;
}
BOOL retVal = YES;
// Find the proper selector to call.
NSString* methodName = [NSString stringWithFormat:@"%@:", command.methodName];
NSString* methodNameWithDict = [NSString stringWithFormat:@"%@:withDict:", command.methodName];
SEL normalSelector = NSSelectorFromString(methodName);
SEL legacySelector = NSSelectorFromString(methodNameWithDict);
// Test for the legacy selector first in case they both exist.
if ([obj respondsToSelector:legacySelector]) {
NSMutableArray* arguments = nil;
NSMutableDictionary* dict = nil;
[command legacyArguments:&arguments andDict:&dict];
//[obj performSelector:legacySelector withObject:arguments withObject:dict];
objc_msgSend(obj, legacySelector, arguments, dict);
} else if ([obj respondsToSelector:normalSelector]) {
//[obj performSelector:normalSelector withObject:command];
objc_msgSend(obj, normalSelector, command);
} else {
// There's no method to call, so throw an error.
NSLog(@"ERROR: Method '%@' not defined in Plugin '%@'", methodName, command.className);
retVal = NO;
}
return retVal;
}
@end