为什么没有autorelease池当我做performSelectorInBackground:? [英] Why is there no autorelease pool when I do performSelectorInBackground:?

查看:117
本文介绍了为什么没有autorelease池当我做performSelectorInBackground:?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在调用一个进入后台线程的方法:

  [self performSelectorInBackground:@selector(loadViewControllerWithIndex :) withObject :[NSNumber numberWithInt:viewControllerIndex]]; 

然后,我有一个方法实现,由选择器调用:

   - (void)loadViewControllerWithIndex:(NSNumber *)indexNumberObj {
NSAutoreleasePool * arPool = [[NSAutoreleasePool alloc] init];
NSInteger vcIndex = [indexNumberObj intValue];

类c;
UIViewController * controller = [viewControllers objectAtIndex:vcIndex];

switch(vcIndex){
case 0:
c = [MyFirstViewController class];
break;
case 1:
c = [MySecondViewController class];
break;
默认值:
NSLog(@加载视图控制器的未知索引:%d,vcIndex); // error
break;
}

if((NSNull *)controller == [NSNull null]){
controller = [[c alloc] initWithNib];
[viewControllers replaceObjectAtIndex:vcIndex withObject:controller];
[controller release];
}

if(controller.view.superview == nil){
UIView * placeholderView = [viewControllerPlaceholderViews objectAtIndex:vcIndex];
[placeholderView addSubview:controller.view];
}

[arPool release];
}

Althoug我创建一个自动释放池有那个线程,我总是得到这个错误:

  2009-05-30 12:03:09.910演示[1827:3f03] *** _NSAutoreleaseNoPool 0x523e50类NSCFNumber自动释放,没有池在位 - 只是泄露
堆栈:(0x95c83f0f 0x95b90442 0x28d3 0x2d42 0x95b96e0d 0x95b969b4 0x93a00155 0x93a00012)

如果我拿走autorelease池,我得到了一大堆这样的消息。我也试图在performSelectorInBackground:的调用周围创建一个自动释放池,但这没有帮助。



我怀疑参数,但我不知道为什么编译器会报告一个NSCFNumber。我缺少一些东西?



我的实例变量都是非原子的。这可能是一个问题?



更新:我也可能怀疑一些变量已经添加到主线程(可能是一个ivar)的自动释放池,现在它trys释放那一个错误的autorelease池?如果是这样,我该如何解决? (这个线程的东西是复杂的))

解决方案

很可能的原因是因为泄漏的对象),是从线程外部传入的参数。因此,此变量属于调用线程(及其自动释放池)



线程调用周围的自动释放池不工作的原因是因为线程创建者(performSelectorInbackground) - 立即返回,很可能在线程仍在运行时。



我建议您在传递参数后, / p>

I am calling a method that goes in a background thread:

[self performSelectorInBackground:@selector(loadViewControllerWithIndex:) withObject:[NSNumber numberWithInt:viewControllerIndex]];

then, I have this method implementation that gets called by the selector:

- (void) loadViewControllerWithIndex:(NSNumber *)indexNumberObj {
    NSAutoreleasePool *arPool = [[NSAutoreleasePool alloc] init];
    NSInteger vcIndex = [indexNumberObj intValue];

    Class c;
    UIViewController *controller = [viewControllers objectAtIndex:vcIndex];

    switch (vcIndex) {
        case 0:
            c = [MyFirstViewController class];
            break;
        case 1:
            c = [MySecondViewController class];
            break;
        default:
            NSLog(@"unknown index for loading view controller: %d", vcIndex); // error
            break;
    }

    if ((NSNull *)controller == [NSNull null]) {
        controller = [[c alloc] initWithNib];
        [viewControllers replaceObjectAtIndex:vcIndex withObject:controller];
        [controller release];
    }

    if (controller.view.superview == nil) {
        UIView *placeholderView = [viewControllerPlaceholderViews objectAtIndex:vcIndex];
        [placeholderView addSubview:controller.view];
    }

    [arPool release];
}

Althoug I do create an autorelease pool there for that thread, I always get this error:

2009-05-30 12:03:09.910 Demo[1827:3f03] *** _NSAutoreleaseNoPool(): Object 0x523e50 of class NSCFNumber autoreleased with no pool in place - just leaking
Stack: (0x95c83f0f 0x95b90442 0x28d3 0x2d42 0x95b96e0d 0x95b969b4 0x93a00155 0x93a00012)

If I take away the autorelease pool, I get a whole bunch of messages like these. I also tried to create an autorelease pool around the call of the performSelectorInBackground:, but that doesn't help.

I suspect the parameter, but I don't know why the compiler complains about an NSCFNumber. Am I missing something?

My Instance variables are all "nonatomic". Can that be a problem?

UPDATE: I may also suspect that some variable has been added to an autorelease pool of the main thread (maybe an ivar), and now it trys to release that one inside the wrong autorelease pool? If so, how could I fix that? (damn, this threading stuff is complex ;) )

解决方案

Most likely the reason for this is because the leaked object (an NSNumber), is a parameter passed in from outside the thread. Hence, this variable belongs to the calling thread (and its autorelease pool)

The reason that the autorelease pool around the thread call doesn't work, is because the thread creator (performSelectorInbackground) - returns immediately, most likely while the thread is still running.

I suggest you do a release on your selector's parameter after passing it in as an argument.

这篇关于为什么没有autorelease池当我做performSelectorInBackground:?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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