【问题标题】:Get block argument from NSInvocation with ARC使用 ARC 从 NSInvocation 获取块参数
【发布时间】:2013-06-04 22:04:14
【问题描述】:

我正在尝试从 NSProxy 的 forwardInvocation 中的 NSInvocation 获取 block 参数: 这是正确的语法吗?会不会泄露内存?

typedef void(^SuccessBlock)(id object);
void *successBlockPointer;
[invocation getArgument:&successBlockPointer atIndex:index];
SuccessBlock successBlock = (__bridge SuccessBlock)successBlockPointer;

或者我应该使用吗?

typedef void(^SuccessBlock)(id object);
SuccessBlock successBlock;
[invocation getArgument:&successBlock atIndex:index];

对象等其他参数类型呢?

__unsafe_unretained id myObject = nil; // I don't think this could be __weak? Is that correct?
[invocation getArgument:&myObject atIndex:index];

我是否必须执行其他操作才能正确释放分配的内存?

提前致谢。

【问题讨论】:

    标签: ios automatic-ref-counting nsinvocation message-forwarding


    【解决方案1】:

    是的。 ARC下,使用不正确

    id myObject = nil; // or any object type or block type
    [invocation getArgument:&myObject atIndex:index];
    

    因为&myObjectid __strong * 类型,即指向强引用的指针。分配给该指针指向的强引用的人必须注意释放先前的值并保留新值。但是,getArgument:atIndex: 不会这样做。

    你是对的。您已经找到了两种正确的方法:1) 使用void * 执行此操作,然后将其分配回对象指针,或 2) 使用__unsafe_unretained 对象指针执行此操作。

    【讨论】:

    • 而且,我假设这两种方法都不会泄漏内存? Instruments 没有报告任何泄漏。对于块或其他对象(非块对象),一种方法是否优于另一种方法?
    • @pshah:是的,这两种方法在内存方面都是正确的。我更喜欢__unsafe_unretained,但没有区别。
    • 非常感谢!非常感谢您的帮助!
    • 这些块作为参数传入时是否需要复制这些块?据我了解,当块作为 id 参数传入时,需要显式复制它们。对于最终调用 forwardInvocation: 的块,我有一个强类型接口(不是 id)。我可以在 forwardInvocation: 本身中以某种方式复制块吗?
    • @pshah:“当它们作为参数传入时”是什么意思?是否需要将块复制到forwardInvocation: 取决于你用它做什么。如果您只是简单地调用调用或将其同步传递给采用块参数的方法,那么不会。如果您需要以某种方式存储它,那么可以。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多