访问OCMock的andDo中的参数时的EXC_BAD_ACCESS [英] EXC_BAD_ACCESS when accessing parameters in andDo of OCMock

查看:131
本文介绍了访问OCMock的andDo中的参数时的EXC_BAD_ACCESS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用OCMock的stub 和Do 方法编写一个代码块。

I am trying to write an block of code using OCMock's stub andDo method.

在这种情况下,正在测试UIImageView扩展类。我想检查扩展名是否使用非零参数调用 [self setImage:] (稍后将使用其他图像比较)。

In this case UIImageView extension class is being tested. I want to check that the extension calls [self setImage:] with parameter that is non-nil (later other image comparison will be used).

使用OCMock的和Do 方法时,在块完成后,测试会以EXC_BAD_ACCESS崩溃。

When using OCMock's andDo method, the test crashes with EXC_BAD_ACCESS after the block completes.

id mockView = [OCMockObject mockForClass:[UIImageView class]];
[[[mockView stub] andDo:^(NSInvocation *invocation)
  {
      UIImage *img;
      [invocation getArgument:&img atIndex:2]; <---- line causing the exception
      somebodySetImage |= (img != nil);

  }] setImage:OCMOCK_ANY];

  [mockView do_something_that_calls_setImage];

我现在找到的唯一解决方案是使用 andCall 代替of andDo ,但这会使测试变得复杂。

The only solution that I've found for now is using andCall instead of andDo, but this complicates the test.

我可以使用 andDo 来避免崩溃吗?

Can I avoid the crash with andDo?

UPDATE
好​​吧,我会尝试在这里给出一个更好的例子:
这是测试代码的新部分:

UPDATE Well, I will try to give a better example here: Here is the new piece of the test code:

- (void)testDownloadingThumbnail
{
    PInfo *_sut = [[PInfo alloc] init];

    __block id target = nil;

    id mock = [OCMockObject mockForClass:[NSOperationQueue class]];

    [[[mock expect] andDo:^(NSInvocation *inv)
    {
        NSInvocationOperation *op;
        [inv getArgument:&op atIndex:2];
        target = [[op invocation] target]; /* replacing this line with STAssert does not help either */
    }] addOperation:OCMOCK_ANY];

    [_sut setDownloadQueue:mock];
    [_sut startDownloadingImagesAsync:YES];

    [mock verify];

    STAssertEqualObjects(target, _sut, @"invalid op target");
}

这是经过测试的代码(PInfo的单一方法):

Here is the tested code (single method from PInfo):

- (void)startDownloadingImagesAsync:(bool)isThumbnailImg
{
    NSInvocationOperation *inv;

    inv = [[NSInvocationOperation alloc] initWithTarget:self
                                     selector:@selector(loadThumbnailWorker:)
                                       object:nil];
    [[self downloadQueue] addOperation:inv];
}

startDownloadingImagesAsync 退出时代码仍然崩溃EXC_BAD_ACCESS。
如果我在 andDo 块中添加一个断点,我看到控件到达这一点并通过 getArgument 检索正确的对象。

The code still crashes upon exit from startDownloadingImagesAsync with EXC_BAD_ACCESS. If I add a breakpoint inside the andDo block, I see that the control reaches this point and retrieves correct objects via getArgument.

然而,如果我在块中使用 getArgument ,它会崩溃我试图做的事情。

Yet, if I use getArgument inside the block, it crashes whatever I try to do.

PS感谢您的帮助。

推荐答案

使用NSProxy的forwardInvocation:方法时遇到了类似的问题。

I ran into a similar problem when using NSProxy's forwardInvocation: method.

你能试试下面的吗?

NSInvocationOperation *op; // Change this line
__unsafe_unretained NSInvocationOperation *op; // to this line

或者另一种方法可能是保留NSInvocation的参数:

Or another approach could be to retain NSInvocation's arguments:

[invocation retainArguments];

http://developer.apple.com/library/ios/documentation/ Cocoa / Reference / Foundation / Classes / NSInvocation_Class / Reference / Reference.html#// apple_ref / occ / instm / NSInvocation / retainArguments

我会尝试稍后添加更详细的解释。

I'll try to add a more detailed explanation later.

这篇关于访问OCMock的andDo中的参数时的EXC_BAD_ACCESS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆