【问题标题】:secondary thread with nsautoreleasepool带有 nsautoreleasepool 的辅助线程
【发布时间】:2010-07-23 15:12:30
【问题描述】:

我用 performSelectorInBackground 调用一个函数,在这个函数中,我声明了

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];   

开头

[pool release];         

最后

但在控制台中,我有这样的消息:

2010-07-23 10:58:30.277 ProjetMission[5914:6913] void _WebThreadLockFromAnyThread(bool), 0x5d5c770: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.

为什么?因为如果我不在函数中放置 nsautoreasepool,我会收到很多这样的消息:

2010-07-23 11:02:58.667 ProjetMission[5951:660f] *** __NSAutoreleaseNoPool(): Object 0x5a7c560 of class NSCFString autoreleased with no pool in place - just leaking

感谢您的帮助

-(void) telechargerDossierWebDansThread
{

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *nomFichier;
    int i;
    BOOL dossierExiste = FALSE;
    int y;
    NSString *reponse;

    NSArray *listeFichier = [self listeFichierATelecharger:[dossierWeb stringByAppendingString:@"/fichier-a-downloader.txt"]];

    [textView performSelectorOnMainThread:@selector(setText:) withObject:@"" waitUntilDone:YES];

    [textView performSelectorOnMainThread:@selector(setText:) withObject:[FonctionUtile concatener: @"Sommaire du download pour le circuit-" chaine2:nomCircuit chaine3:@"" chaine4:@"\n"] waitUntilDone:YES];
    [textView performSelectorOnMainThread:@selector(setText:) withObject:[FonctionUtile concatener:textView.text chaine2:@"Nombre de fichier à downloader => " chaine3:[NSString stringWithFormat:@"%d", [listeFichier count]]  chaine4:@"\n"] waitUntilDone:YES]; 

    if ([listeFichier count] > 0) 
    {

        if ([ManipulationFichierDossier supprimerDossierFichier:cheminDossierSurIpod] || ![ManipulationFichierDossier VerifierSiDossierFichierExiste:cheminDossierSurIpod] ) {
            dossierExiste =  [ManipulationFichierDossier creerDossier:cheminDossierSurIpod];
        }

        if (dossierExiste)
        {

            [textView performSelectorOnMainThread:@selector(setText:) withObject:[FonctionUtile concatener:textView.text chaine2:[FonctionUtile padderChaine:@"Fichiers à downloader" :27 :@" " :TRUE] chaine3:@"Download succès" chaine4:@"\n" ] waitUntilDone:YES];

            y = 70;

            for (i = 0; i < [listeFichier count]; i++)
            {
                nomFichier = [[listeFichier objectAtIndex:i]retain];

                if ([self TelechargerFichierUnique:nomFichier :[FonctionUtile concatener:dossierWeb chaine2:@"/" chaine3:nomFichier chaine4:@""] :cheminDossierSurIpod :TRUE])
                {

                    reponse = @"Oui";
                }
                else                  
                {
                    reponse = @"Non";
                }

                [textView performSelectorOnMainThread:@selector(setText:) withObject:[FonctionUtile concatener:textView.text chaine2:[FonctionUtile padderChaine:nomFichier :27 :@" " :TRUE] chaine3:reponse chaine4:@"\n"] waitUntilDone:YES];

                y = y +20;
            }
        }
    }

    [textView performSelectorOnMainThread:@selector(setText:) withObject:[FonctionUtile concatener:textView.text chaine2: @"Fin du download pour le circuit-" chaine3:nomCircuit chaine4:@""] waitUntilDone:YES];

    [pool release];
}

此函数由 performSelectorInBackground 调用。

【问题讨论】:

  • 您收到的消息与使用 NSAutoreleasePool 无关。您似乎正在从辅助线程更新 UI 元素,但它应该只在主线程上执行。
  • 没错,我调用 [textView performSelectorOnMainThread:@selector(setText:) withObject:@"test" waitUntilDone:YES];但是这样做是不正确的吗?因为如果我不放这一行,我的控制台中就没有消息了。
  • 您有一个名为padderChaine:::concatener:chaine2:chaine3:chaine4: 的方法?哇!不要那样做!交错的参数旨在由每个参数的冒号前面的选择器部分来描述。
  • 我英文不太好,听不懂你这句话,你能不能换个说法再解释一下。
  • 将方法命名为-method:::: 被认为是错误的形式。您应该在冒号之间添加描述性术语,以使该方法更具可读性。以 Apple 如何命名 Cocoa API 中的方法为例,了解如何设置代码样式。

标签: iphone objective-c


【解决方案1】:

拥有NSAutoreleasePool 是正确的。错误消息似乎只是表明您正在从后台线程操作 UI 元素(可能是 UIWebView)。正如错误消息所说,这不是 A Good Thing™。

【讨论】:

  • 为什么不是好事?此行在循环中 [textView performSelectorOnMainThread:@selector(setText:) withObject:@"test" waitUntilDone:YES] 我把它放在辅助线程中,因为如果它在主线程中,则 textview 仅在函数结束时刷新.
  • @alex 在主线程上操作,而不是后台线程。该错误消息似乎表明正在发生其他事情。也许你可以把身体或你的方法放在问题中?
  • 我把我的功能放在了问题中!
  • @alex - 除非在您的自定义类中发生某些事情,否则我在您的新代码中看到问题的唯一地方是textView.text,您可以从后台线程访问 textView 上的属性。这可能是触发警告的原因。
猜你喜欢
  • 1970-01-01
  • 2011-06-11
  • 2012-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多