我试图从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)
我是否必须做其他事情以正确释放分配的内存?
提前致谢.
将http web api请求转发到另一台服务器的最佳方法是什么?
这是我正在尝试的:
我有一个.NET项目,当我得到某些API请求时,我想修改请求,将其转发到另一台服务器,并返回第二台服务器发送的响应.
我正在做以下事情:
[Route("forward/{*api}")]
public HttpResponseMessage GetRequest(HttpRequestMessage request)
{
string redirectUri = "http://productsapi.azurewebsites.net/api/products/2";
HttpRequestMessage forwardRequest = request.Clone(redirectUri);
HttpClient client = new HttpClient();
Task<HttpResponseMessage> response = client.SendAsync(forwardRequest);
Task.WaitAll(new Task[] { response } );
HttpResponseMessage result = response.Result;
return result;
}
Run Code Online (Sandbox Code Playgroud)
克隆方法定义为:
public static HttpRequestMessage Clone(this HttpRequestMessage req, string newUri)
{
HttpRequestMessage clone = new HttpRequestMessage(req.Method, newUri);
if (req.Method != HttpMethod.Get)
{
clone.Content = req.Content;
}
clone.Version = req.Version;
foreach (KeyValuePair<string, object> prop in req.Properties)
{
clone.Properties.Add(prop);
}
foreach …Run Code Online (Sandbox Code Playgroud) (gdb) bt
#0 0x302ac924 in ___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION___ ()
#1 0x92077e3b in objc_exception_throw ()
#2 0x302d6ffb in -[NSObject doesNotRecognizeSelector:] ()
#3 0x3026e056 in ___forwarding___ ()
#4 0x3024a0a2 in __forwarding_prep_0___ ()
#5 0x00004ae9 in -[GameObject doesTouch:] (self=0xe893a0, _cmd=0x643ee, obj=0xe82e20) at /Users/aaa/Desktop/CPT/Game/Classes/GameObject.m:220
#6 0x00006e05 in -[StaticGrid checkTouchNearest:] (self=0xe82f20, _cmd=0x64ec3, obj=0xe893a0) at /Users/aaa/Desktop/CPT/Game/Classes/StaticGrid.m:62
#7 0x0000a393 in -[EAGLView touchesBegan:withEvent:] (self=0xe8dad0, _cmd=0x3199fa3c, touches=0x632c0b0, event=0xe14590) at /Users/aaa/Desktop/CPT/Game/Classes/EAGLView.m:459
#8 0x30910f33 in -[UIWindow _sendTouchesForEvent:] ()
#9 0x308faecb in -[UIApplication sendEvent:] ()
#10 0x309013e1 in _UIApplicationHandleEvent ()
#11 0x32046375 in PurpleEventCallback …Run Code Online (Sandbox Code Playgroud) 我只是在研究Objective-C的"消息转发".我编写了一个测试程序来验证我是否可以在运行时"吞下"一个无法识别的选择器.所以我这样做了:
- (void) forwardInvocation: (NSInvocation *) anInvocation {
if ([anInvocation selector] == @selector(testMessage)){
NSLog(@"Unknow message");
}
return;
}
Run Code Online (Sandbox Code Playgroud)
但它仍然在运行时抛出"无法识别的选择器"错误.在搜索了解决方案后,我知道我需要覆盖方法"methodSignatureForSelector:",所以我编写了另一个名为"Proxy"的代理类,并使用以下方法:
(NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
if ([Proxy instancesRespondToSelector: selector]) {
return [Proxy instanceMethodSignatureForSelector: selector];
}
return [super methodSignatureForSelector:selector];
}
Run Code Online (Sandbox Code Playgroud)
但实际上,我不想实现这样的另一个代理类来完成这个方法.我想做的就是忽略这个未知的选择器.但是,如果我只是键入它,它不起作用:
(NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
return [super methodSignatureForSelector:selector];
}
Run Code Online (Sandbox Code Playgroud)
所以,我想知道有什么办法可以简单地"吞下"这个错误吗?(不使用异常处理程序,我想采用"转发"方式).谢谢!
我想在我的SZNUnmanagedReference类上使用消息转发.它有这个属性:
@property (nonatomic, strong) NSSet *authors;
@property (nonatomic, strong) SZNReferenceDescriptor *referenceDescriptor;
Run Code Online (Sandbox Code Playgroud)
基本上,当UnmanagedReference的实例收到消息时authorsString,它应该转发给它referenceDescriptor,它有一个名为的方法- (NSString *)authorsStringWithSet:(NSSet *)authors.
所以,我写道SZNUnmanagedReference.m:
- (void)forwardInvocation:(NSInvocation *)anInvocation {
SEL aSelector = anInvocation.selector;
if ([NSStringFromSelector(aSelector) isEqualToString:NSStringFromSelector(@selector(authorsString))]) {
NSMethodSignature *signature = [self.referenceDescriptor methodSignatureForSelector:@selector(authorsStringWithSet:)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
NSSet *authors = [NSSet setWithSet:self.authors];
[invocation setSelector:@selector(authorsStringWithSet:)];
[invocation setArgument:&authors atIndex:2];
[invocation setTarget:self.referenceDescriptor];
[invocation invoke];
} else {
[self doesNotRecognizeSelector:aSelector];
}
}
- (BOOL)respondsToSelector:(SEL)aSelector {
if ([super respondsToSelector:aSelector]) {
return YES;
} else if ([NSStringFromSelector(aSelector) …Run Code Online (Sandbox Code Playgroud) 我正在努力通过Facade类转发类方法.
为了澄清,我推翻了以下所有方法:
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
-(void)forwardInvocation:(NSInvocation *)anInvocation
+(BOOL)instancesRespondToSelector:(SEL)aSelector
+(NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector
+(IMP)instanceMethodForSelector:(SEL)aSelector
+(BOOL)resolveClassMethod:(SEL)sel
+(BOOL)resolveInstanceMethod:(SEL)sel
Run Code Online (Sandbox Code Playgroud)
..然而,对于类方法,唯一要调用的是+resolveClassMethod.从那里,无论我是否返回YES,我都会立即得到一个无法识别的选择器异常.
这是怎么回事?
类消息转发与实例消息转发的工作方式不同吗?
同样,为什么没有+forwardInvocation类方法呢?
任何帮助将不胜感激.
我有一个正在转发接收消息的对象。它没有实现使用forwardInvocation. 但是,methodSignatureForSelector由于程序的组织方式,在某些时候不会总是返回有效的方法签名。如何吞下由缺少的方法签名生成的异常?覆盖doesNotRecognizeSelector不起作用。谢谢。
objective-c objective-c-runtime message-forwarding nsinvocation
因此,当我遇到一些稀缺资源时,我正在研究消息转发并运行一些单元测试,这些资源包括苹果公司自己的品牌文件,forwardInvocation:据我所知需要使用这些文件methodSignatureForSelector:。
现在,我得到了一个大致的想法,methodSignatureForSelector:即查看您试图将消息转发到的对象是否具有匹配的方法名称和参数,以便可以调用forwardInvocation:我的问题,这是为什么为什么在apples文档中它说要调用methodSignatureForSelector:类似的超类的实现所以...
- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature* signature = [super methodSignatureForSelector:selector];
if (!signature) {
signature = [surrogate methodSignatureForSelector:selector];
}
return signature;
}
Run Code Online (Sandbox Code Playgroud)
对我来说,这似乎是在说:“如果我继承的所有类都没有方法可以处理此方法,请检查替代对象是否具有此功能。”
苹果提供的例子是,在谈判方法上,战士代替外交官行事。在这个例子中,我看不出为什么要检查战士或父母中的任何一个是否有适当的方法签名来转发。因此,这使我相信存在另一个原因,这是我无法想到的,有人可以给我一个例子或帮助弄清楚我可能遗漏的地方吗?
TL; DR
为什么需要[super methodSignatureForSelector:selector];?
objective-c ×7
ios ×3
nsinvocation ×2
c# ×1
cocoa ×1
cocoa-touch ×1
http ×1
nsobject ×1
stack-trace ×1