标签: nsinvocation

NSInvocation和ARC(自动引用计数)

当我尝试将当前代码迁移到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的所有权的对象一起使用是不安全的."

我怎么能绕过这个?

cocoa nsinvocation automatic-ref-counting

9
推荐指数
2
解决办法
3689
查看次数

NSInvocation和内存问题

所以我来自Java世界,我们对内存管理问题一无所知.在大多数情况下,ARC已经救了我的屁股,但这里有些让我难过的东西.基本上我使用NSInvocations来做一些事情,在进行下面的代码修改之前,我遇到了一些讨厌的内存问题.由于我做了这些修改,内存崩溃已经消失,但我通常非常害怕我不理解的代码.我这样做了吗?

之前:各种内存问题:

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[target class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:target];
[invocation setArgument:&data atIndex:2];
[invocation setArgument:&arg atIndex:3];
[invocation invoke];

NSString *returnValue;
[invocation getReturnValue:&returnValue];
Run Code Online (Sandbox Code Playgroud)

之后:没有内存问题,但我不确定我是否正确:

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[target class] instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:target];
[invocation setArgument:&data atIndex:2];
[invocation setArgument:&arg atIndex:3];
[invocation invoke];

CFTypeRef result;
[invocation getReturnValue:&result];

if (result)
    CFRetain(result);

NSString *returnValue = (__bridge_transfer NSString *)result;
Run Code Online (Sandbox Code Playgroud)

编辑:

我只想根据下面的答案添加,我使用了objc_msgSend,因此:

NSString * returnValue = objc_msgSend(target, selector, data, arg);
Run Code Online (Sandbox Code Playgroud)

它解决了所有内存问题,而且看起来更简单.如果您发现此问题,请发表评论.

cocoa-touch memory-management objective-c nsinvocation ios

8
推荐指数
1
解决办法
1900
查看次数

是 - [NSInvocation retainArguments]复制块?

NSInvocation-retainArguments当你不NSInvocation立即运行时,它的方法很有用,但是稍后会这样做; 它保留了对象参数,因此它们在此期间保持有效.

众所周知,应该复制块参数而不是保留.我的问题是,是否-retainArguments知道复制而不是在块类型时保留参数?文档并没有表明它确实如此,但它似乎是一件容易和明智的事情.

更新: iOS 7中的行为似乎已经发生了变化.我刚刚对此进行了测试,并且在iOS 6.1和之前,-retainArguments没有复制块类型的参数.在iOS 7及更高版本中,-retainArguments复制块类型的参数.文档-retainArguments已更新,说它复制块,但它没有说明行为何时发生变化(这对支持旧操作系统的人来说真的很危险).

objective-c retain nsinvocation objective-c-blocks

7
推荐指数
1
解决办法
1395
查看次数

带块参数的NSInvocation

我正在尝试将块参数传递给a NSInvocation,但应用程序崩溃了.调用发出网络请求并调用成功或失败块.我认为问题是在网络请求完成之前会释放块.我设法让它与一些Block_copyhackery 一起工作,它没有使用Instruments报告任何泄漏.

问题: - 即使静态分析仪或仪器没有报告,泄漏是否可能存在? - 有没有更好的方法来"保留"该区块?

// Create the NSInvocation
NSMethodSignature *methodSignature = [target methodSignatureForSelector:selector];
NSInvocation* invoc = [NSInvocation invocationWithMethodSignature:methodSignature];
[invoc setTarget:target];
[invoc setSelector:selector];

// Create success and error blocks.
void (^successBlock)(id successResponse) = ^(id successResponse) {
    // Some success code here ...
};

void (^errorBlock)(NSError *error) = ^(NSError *error) {
    // Some failure code here ...
};

/*
Without the two Block_copy lines, the block gets dealloced too soon
and the app crashes with …
Run Code Online (Sandbox Code Playgroud)

dealloc nsinvocation ios objective-c-blocks

7
推荐指数
1
解决办法
4012
查看次数

如何将参数传递给NSTimer中调用的方法

我有一个调用方法的计时器,但这个方法需要一个参数:

theTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(timer) userInfo:nil repeats:YES];
Run Code Online (Sandbox Code Playgroud)

应该

theTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(timer:game) userInfo:nil repeats:YES];
Run Code Online (Sandbox Code Playgroud)

现在这种语法似乎不对.我试过NSInvocation但我遇到了一些问题:

timerInvocation = [NSInvocation invocationWithMethodSignature:
        [self methodSignatureForSelector:@selector(timer:game)]];

theTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval
        invocation:timerInvocation
        repeats:YES];
Run Code Online (Sandbox Code Playgroud)

我该如何使用Invocation?

arguments objective-c nstimer nsinvocation

6
推荐指数
2
解决办法
1万
查看次数

iOS - 不能使用'super'作为参考?

我正在尝试使用一个NSInvocation从子类调用超类方法.涉及的代码相对简单,如下所示:

- (NSInvocation*) invocationWithSelector:(SEL)selector {
    NSInvocation* call = [[NSInvocation alloc] init];
    [call retainArguments];
    call.target = super;  //ERROR:  use of undeclared identifier 'super'

    call.selector = @selector(selector);

    return call;
}
Run Code Online (Sandbox Code Playgroud)

这对我来说有点奇怪,因为我一直认为它super遵循的规则几乎相同self(即它可以被视为对相关对象的直接引用并分配给变量,用作返回值等) .看来实际情况并非如此.

无论如何,是否有任何简单的方法来让我NSInvocation的目标超类实现(我不能self用作目标,因为子类重写超类方法),或者我是否需要寻找其他方法?

inheritance cocoa-touch objective-c nsinvocation

6
推荐指数
1
解决办法
2704
查看次数

NSInvocation getReturnValue:在forwardInvocation内调用:使返回的对象调用dealloc:

test.m是我用来测试行为的独立文件.

编译:clang test.m -o test.app -fobjc-arc -ObjC -framework Foundation.确保已安装Xcode命令行工具.

#import <Foundation/Foundation.h>

@protocol Protocol

@optional
- (id)objProxyMethod;

@end

@interface ReturnObject: NSObject

@end

@interface Test : NSObject <Protocol>

@end

@interface Proxy : NSObject <Protocol>

- (id)objProxyMethod;

@end

@implementation ReturnObject

- (void)dealloc {
    NSLog(@"ERROR:");
    NSLog(@"I'm getting deallocated!");
    NSLog(@"This shouldn't happen!");
}

- (NSString *)description {
    return @"Blank object!";
}

@end

@implementation Proxy

- (id)objProxyMethod {
    NSLog(@"in [Proxy objProxyMethod]!");
    return [[ReturnObject alloc] init];
}

@end

@implementation Test

- (void)forwardInvocation:(NSInvocation *)invocation …
Run Code Online (Sandbox Code Playgroud)

objective-c nsinvocation

6
推荐指数
1
解决办法
3471
查看次数

哪一个更好地使用NSInvocation或NSNotificationCentre或Delegate方法

在整个项目中哪一个更好用于将数据从一个类流向另一个类?

NSInvocation

NSNotificationCentre

delegate 方法

或者我不知道的任何其他方法?

iphone delegates nsinvocation nsnotificationcenter ios

6
推荐指数
1
解决办法
377
查看次数

为什么创建NSInvocation必须指定选择器两次

以下是我从Apple的"计时器编程主题"中看到的示例代码:

NSMethodSignature *methodSignature = [self
methodSignatureForSelector:@selector(invocationMethod:)];
NSInvocation *invocation = [NSInvocation
invocationWithMethodSignature:methodSignature];
[invocation setTarget:self];
[invocation setSelector:@selector(invocationMethod:)];
NSDate *startDate = [NSDate date];
[invocation setArgument:&startDate atIndex:2];
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我们必须指定invocationMethod:一次在NSMethodSignature中,然后第二次NSInvocationsetSelector.对我来说,这似乎是多余的,苹果设计有这样的理由吗?

nsinvocation ios

6
推荐指数
1
解决办法
407
查看次数

调用阻止iOS

我尝试调用一些块,但我遇到了一个EXC_BAD_ACCESS.

-(void) methodA {
   self.block = ^ {
       [self methodB];
   };
}

-(void) webViewDidFinishLoad:(UIWebView *)webView {
       [block invoke]; // error here (block is not valid id type).
}

-(void)methodB {
    //do something
}
Run Code Online (Sandbox Code Playgroud)

有关为什么会发生这种情况的任何想法?

objective-c nsinvocation ios objective-c-blocks

5
推荐指数
2
解决办法
2万
查看次数