- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在使用包含 double 或任何未对齐的 64 位类型的结构设置 NSInvocation 的参数时遇到一个奇怪的问题(我在结构的开头用 char 偏移它)。问题是一些字节在设置参数后被清除。这个问题在ARM7上出现,但在iOS模拟器上没有。
我正在使用 LLVM 3.0 和 Xcode 4.2
这是我的代码和测试结果:
NSInvocation+Extension.h
@interface NSInvocation (Extension)
+ (NSInvocation*) invocationWithTarget: (id)aTarget
selector: (SEL)aSelector
retainArguments: (BOOL)aRetainArguments, ...;
- (void) setArguments: (va_list)aArgList;
- (void) setArguments: (va_list)aArgList atIndex: (NSInteger)aIndex;
@end // NSInvocation (Extension)
NSInvocation+Extension.m
#import <objc/runtime.h>
#import "NSInvocation+Extension.h"
@implementation NSInvocation (Extension)
+ (NSInvocation*) invocationWithTarget: (id)aTarget
selector: (SEL)aSelector
retainArguments: (BOOL)aRetainArguments, ...
{
NSMethodSignature* signature = [aTarget methodSignatureForSelector: aSelector];
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: signature];
if (aRetainArguments)
{
[invocation retainArguments];
}
[invocation setTarget: aTarget];
[invocation setSelector: aSelector];
va_list argList;
va_start(argList, aRetainArguments);
[invocation setArguments: argList];
va_end(argList);
return invocation;
}
- (void) setArguments: (va_list)aArgList
{
[self setArguments: aArgList atIndex: 0];
}
- (void) setArguments: (va_list)aArgList atIndex: (NSInteger)aIndex
{
// Arguments are aligned on machine word boundaries
const NSUInteger KOffset = sizeof(size_t) - 1;
UInt8* argPtr = (UInt8*)aArgList;
NSMethodSignature* signature = [self methodSignature];
// Indices 0 and 1 indicate the hidden arguments self and _cmd respectively.
for (int index = aIndex + 2; index < [signature numberOfArguments]; ++index)
{
const char* type = [signature getArgumentTypeAtIndex: index];
NSUInteger size = 0;
NSGetSizeAndAlignment(type, &size, NULL);
[self setArgument: argPtr atIndex: index];
argPtr += (size + KOffset) & ~KOffset;
}
}
@end // NSInvocation (Extension)
声明要调用的方法和数据结构
- (void) arg1: (char)aArg1 arg2: (char)aArg2 arg3: (TEST)aArg3 arg4: (char)aArg4;
typedef struct test {
char c;
double s;
char t;
void* b;
char tu;
} TEST;
调用代码
TEST df = { 'A', 12345678.0, 'B', (void*)2, 'C' };
char buf[100] = {0};
NSInvocation* ik = [NSInvocation invocationWithTarget: self selector: @selector(arg1:arg2:arg3:arg4:) retainArguments: NO, '1', '2', df, '3'];
[ik getArgument: &buf atIndex: 4];
ARM7 上 buf 的内容(字节 8、9、10 和 11 设置为零,这弄乱了 double 值)
41 00 00 00 00 00 00 00 29 8C 67 41 42 00 00 00 02 00 00 00 43 00 00 00
i386 模拟器上 buf 的内容(如预期的那样)
41 00 00 00 00 00 00 C0 29 8C 67 41 42 00 00 00 02 00 00 00 43 00 00 00
最佳答案
首先想到的是,您确实必须使用 va_arg 来访问可变参数列表中的连续参数。您无法像您那样假设参数被安排在一 block 漂亮的连续内存中。一方面,ARM ABI 表示前四个参数在寄存器中传递。
va_list 不一定只是一个指针,它是一个不透明的类型。您对 uint8_t* 的转换几乎肯定是无效的。
关于objective-c - iOS NSInvocation setArgument : atIndex: does not work with struct on ARM builds,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9965116/
我正在使用 NSInvocation 调用一个我在编译时不知道的方法。 它工作正常,因为我没有找到如何传递 NSError** 类型的参数。 举个例子,假设我想从 NSFileManager 调用方法
以下代码抛出异常。 vcClass 是一个 Class 对象(继承自 UIViewController)。 Self 包含 我的实现 viewWillAppear: SEL viewWillAppea
既然可以直接调用方法,为什么还要使用 NSInvocation?需要问这个问题是因为我无法理解需要使用这个类。与仅调用如下方法相比,使用它有什么优势。 [myArray addObject:mySt
这个问题在这里已经有了答案: NSInvocation getReturnValue: called inside forwardInvocation: makes the returned obj
我想在未来安排一个函数调用。我正在使用 Swift。 我想回调一个私有(private)方法并返回一个 Promise(来自 PromiseKit) 我见过的所有例子都用到了 NSTimer.sche
什么是NSInspiration?何时以及如何使用它? 最佳答案 NSInvocation是消息发送的具体化。换句话说,它是一个代表消息发送的对象。 假设您的 Foo 类有一个名为 -[Foo foo
我创建了一个弱目标定时器类,当目标被释放时,定时器不会触发并自动失效。代码是这样的: //ViewController.m @interface TestObj : NSObject @end @im
有谁知道如何将 NSInvocation 的参数设置为 nil ?我正在尝试使用 OCMock,我希望这种期望返回 nil。问题是调用该方法时我需要做一些其他事情,正如您在示例中看到的那样,这就是为什
我有一个方法,它采用类似这样的可变参数,参数以 nil 结尾。 -(void)manyParams:(NSString *)st, ... { va_list argList; va_
我想使用一个将指向 NSError 对象的指针作为参数的方法来创建一个 NSInvocation 对象。这方面的一个例子是方法 - - (BOOL)writeToFile:(NSString *)pa
下面是我从Apple的“Timer Programming Topics”看到的示例代码: NSMethodSignature *methodSignature = [self methodSigna
我如何(或什至可以)将 nil 参数传递给 NSInvocation 对象? 我试着这样做: NSMethodSignature* signature = [AClass instanceMethod
我正在尝试在 Swift 中创建一个可重用的测试工具,子类将扩展测试工具以提供被测实例,并且可以添加它们自己的特定于子类的测试方法,如下所示: class FooTestHarness: XCTest
NSInvocation 究竟是如何工作的?有好的介绍吗? 我在理解以下代码(来自 Cocoa Programming for Mac OS X,第 3 版)的工作原理方面特别有问题,但我也能够独立于
我使用运行时特性向类中添加了一个类方法,但是NSInvocation 无法使用该方法。我的代码是这样的: id metaClass = object_getClass((id)protocolClas
我对 NSInvocation 有一个奇怪的问题。当网络操作完成时,我将它用作返回回调。让我更详细地解释一下前面的句子: 我正在使用通过 TCP 套接字工作的定制网络协议(protocol),并且我有
我认为我犯了一个根本性的错误,但我一生都看不到它。 我正在从 C++ 类(已锁定)中调用 Objective-C 对象的方法。我正在使用 NSInvocation 来防止我不得不编写数百个方法来访问这
我们有以下方法,适用于对象。它接受一个对象的方法并将结果放在 returnValueContainer 中: + (void)invokePrivateMethod:(SEL)selector ret
我收到这条消息: “(null):无法识别的选择器发送到类 0x3f52e824” 我试过的基本代码: SEL sel = @selector(applyProperties:toObject:);
我试图将 block 参数传递给 NSInvocation,但应用程序崩溃了。调用发出网络请求并调用成功或失败 block 。我认为问题在于 block 在网络请求完成之前被释放。我设法让它与一些 B
我是一名优秀的程序员,十分优秀!