我有一个数组,我正在迭代并寻找一个特定的标志.如果标志值为nil,我正在调用一个生成调用对象并返回调用结果的方法.
我的代码结构如下
for(NSString *key in [taxiPlanes allKeys])
{
Plane *currentPlane = [taxiPlanes objectForKey:key];
if(currentPlane.currentAction == nil)
{
NSString *selector = [[currentPlane planeTakeoffSequence] firstObject];
currentPlane.currentAction = selector;
// Calling for NSInvocation in [self ...]
NSArray *action = [NSArray arrayWithArray:[self operationFromTakeoffAction:currentPlane.currentAction AtPoint:currentPlane.position]];
NSLog(@"%@",action);
}
}
Run Code Online (Sandbox Code Playgroud)
生成NSInvocation的方法
-(NSArray *) operationFromTakeoffAction:(NSString *) action AtPoint:(CGPoint) flightPoint
{
NSMethodSignature *methodSignature = [FlightOperations instanceMethodSignatureForSelector:NSSelectorFromString(action)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
[invocation setTarget:fOps];
[invocation setSelector:NSSelectorFromString(action)];
[invocation setArgument:&flightPoint atIndex:2];
NSArray *resultSet = [NSArray alloc]init];
[invocation invoke];
[invocation getReturnValue:&resultSet];
return resultSet; …Run Code Online (Sandbox Code Playgroud) 我无法让forwardInvocation工作.出于某种原因,Objective-C运行时完全忽略了我的forwardInvocation:方法并抛出了无法识别的选择器异常.
我的测试代码如下:
@interface InvocationTest : NSObject
{
}
+ (void) runTest;
@end
@interface FullClass: NSObject
{
int value;
}
@property(readwrite,assign) int value;
@end
@implementation FullClass
@synthesize value;
@end
@interface SparseClass: NSObject
{
}
@end
@implementation SparseClass
- (void)forwardInvocation:(NSInvocation *)forwardedInvocation
{
NSLog(@"ForawrdInvocation called");
FullClass* proxy = [[[FullClass alloc] init] autorelease];
proxy.value = 42;
[forwardedInvocation invokeWithTarget:proxy];
}
@end
@implementation InvocationTest
+ (void) runTest
{
SparseClass* sparse = [[[SparseClass alloc] init] autorelease];
NSLog(@"Value = %d", [sparse value]);
}
@end
Run Code Online (Sandbox Code Playgroud)
我正在处理来自以下资源的信息:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html#//apple_ref/doc/uid/TP40008048-CH105 http://cocoawithlove.com/2008/ 03 …
我想NSURLConnection 在后台模式下做,因为它的响应有很多数据.论坛要求使用Apple的有限长度编码didEnterBackground.但我想避免使用我通过下面的代码它.相反NSOperation有NSInvocation作为,但它不工作.connectToServer有NSURLConnection操作.请帮忙吗?didReceiveData,didReceiveResponse委托方法不调用?
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(connectToServer)
object:nil];
[queue addOperation:operation];
[operation release];
[queue autorelease];
-(void)connectToServer
{
NSURL *url = [NSURL URLWithString:@"http://www.google.com"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *theConnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];
if( theConnection )
{
webData = [[NSMutableData data] retain];
}
else
{
NSLog(@"theConnection is NULL");
}
}
Run Code Online (Sandbox Code Playgroud) 我试图调用一个返回double使用的方法NSInvocation.但我发现它无法在64位iOS应用程序中运行.它适用于OS X,模拟器 - 32位和64位 - iPad 2和带有32位版本的iPad Air.只有iPad Air设备上的64位版本才有此问题.
这是演示问题的代码:
NSMethodSignature *signature = [NSString instanceMethodSignatureForSelector:@selector(doubleValue)];
for (int i = 0; i < 10; i++) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
NSString *str = [NSString stringWithFormat:@"%d", i];
[invocation setTarget:str];
[invocation setSelector:@selector(doubleValue)];
[invocation invoke];
union {
double d;
uint64_t u;
} d;
[invocation getReturnValue:&d.d];
NSLog(@"%lf, %llx", d.d, d.u);
}
Run Code Online (Sandbox Code Playgroud)
预期产出
2013-11-09 22:34:18.645 test[49075:907] 0.000000, 0
2013-11-09 22:34:18.647 test[49075:907] 1.000000, 3ff0000000000000
2013-11-09 22:34:18.648 test[49075:907] 2.000000, 4000000000000000
2013-11-09 22:34:18.649 test[49075:907] …Run Code Online (Sandbox Code Playgroud) 我使用以下NSInvocation代码形式Matt Gallagher作为我的Undo/Redo代码.虽然使用最新版本的xCode但我没有收到警告:NSInvocation(ForwardedConstruction).m:28:12:定义了'InvocationProxy'类而没有指定基类
该守则运作良好,但我团队中的其他人(我也是)也不喜欢看警告.我希望Class尽可能的修饰,所以我不想要NSObject中的所有方法.
欢迎任何建议!
谢谢!
NSInvocation的(ForwardedConstruction).H
//
// NSInvocation(ForwardedConstruction).h
//
// Created by Matt Gallagher on 19/03/07.
// Copyright 2007 Matt Gallagher. All rights reserved.
//
// Permission is given to use this source code file without charge in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is …Run Code Online (Sandbox Code Playgroud) 我试图从NSProxy的forwardInvocation中的NSInvocation获取块参数:这是正确的语法吗?它会泄漏内存吗?
typedef void(^SuccessBlock)(id object);
void *successBlockPointer;
[invocation getArgument:&successBlockPointer atIndex:index];
SuccessBlock successBlock = (__bridge SuccessBlock)successBlockPointer;
Run Code Online (Sandbox Code Playgroud)
或者我应该使用?
typedef void(^SuccessBlock)(id object);
SuccessBlock successBlock;
[invocation getArgument:&successBlock atIndex:index];
Run Code Online (Sandbox Code Playgroud)
那些像对象一样的其他参数类型呢?
__unsafe_unretained id myObject = nil; // I don't think this could be __weak? Is that correct?
[invocation getArgument:&myObject atIndex:index];
Run Code Online (Sandbox Code Playgroud)
我是否必须做其他事情以正确释放分配的内存?
提前致谢.
我是GCD和线程的新手.我已经完成了教程并且非常困惑.有人可以用简单的话来解释.请不要建议苹果开发者链接..
提前致谢 !
iphone multithreading nsoperationqueue grand-central-dispatch nsinvocation
我正在寻找一种方法来NSInvocation调用特定的IMP.默认情况下,它调用IMP它可以找到的"最低" (即最近被覆盖的版本),但是我正在寻找一种方法让它IMP在继承链中从更高的位置调用它.在IMP我想要调用动态确定,否则我可以使用super关键字或类似的东西.
我的想法是使用-forwardInvocation:机制来捕获消息(简单且已经工作),然后改变IMP它,所以它转到一个既不是super实现也不是最远的后代实现的方法.(硬)
我发现远程关闭的唯一东西是AspectObjectiveC,但这需要libffi,这使得它与iOS兼容.理想情况下,我希望这是跨平台的.
有任何想法吗?
免责声明:我只是在试验
试试@bbum关于蹦床功能的想法
所以我觉得我已经把事情搞得一团糟了; 我有以下蹦床,通过正确添加class_addMethod(),它确实输入:
id dd_trampolineFunction(id self, SEL _cmd, ...) {
IMP imp = [self retrieveTheProperIMP];
self = [self retrieveTheProperSelfObject];
asm(
"jmp %0\n"
:
: "r" (imp)
);
return nil; //to shut up the compiler
}
Run Code Online (Sandbox Code Playgroud)
我已经验证了正确的自我和正确的IMP在JMP之前是正确的事情,并且_cmd参数也正确地进入.(换句话说,我正确地添加了这种方法).
然而,事情正在发生.我有时会发现自己跳到了零的方法(通常不正确的)self和_cmd.其他时候我只是在EXC_BAD_ACCESS的中途崩溃.想法?(自从我在汇编中做了很多事以来已经很久了...)我在x86_64上测试了这个.
我不明白为什么我们必须setSelector在NSInvocation对象上调用该方法,因为该信息已经通过invocationWithMethodSignature.
要创建NSInvocation对象,我们执行以下操作:
SEL someSelector;
NSMethodSignature *signature;
NSInvocation *invocation;
someSelector = @selector(sayHelloWithString:);
//Here we use the selector to create the signature
signature = [SomeObject instanceMethodSignatureForSelector:someSelector];
invocation = [NSInvocation invocationWithMethodSignature:signature];
//Here, we again set the same selector
[invocation setSelector:someSelector];
[invocation setTarget:someObjectInstance];
[invocation setArgument:@"Loving C" atIndex:2];
Run Code Online (Sandbox Code Playgroud)
请注意,我们将选择器传递给[SomeObject instanceMethodSignatureForSelector: someSelector];并再次传递给[invocation setSelector:someSelector];.
有什么我想念的吗?
当我尝试将当前代码迁移到ARC时,每当我将NSString作为NSInvocation参数传递时,我都会收到错误.
例:
NSInvocation inv = ...;
NSString *one = @"Hello World!";
[inv setArgument:&one atIndex:2];
Run Code Online (Sandbox Code Playgroud)
当我使用编辑菜单中的重构 - >转换为Objective-C ARC选项时,会发生错误.文本是"NSInvocation的setArgument与不具有__unsafe_retained的所有权的对象一起使用是不安全的."
我怎么能绕过这个?
nsinvocation ×10
objective-c ×7
ios ×5
iphone ×2
arm64 ×1
cocoa ×1
dynamic ×1
imp ×1
ipad ×1
methods ×1
nsoperation ×1
selector ×1