3

加载应用程序后,我正在将图像延迟加载到数组中。我尝试过使用 NSMutableArray 和 NSArray (一旦创建数组,我就不需要更改数组),但后者在我身上崩溃了。

...
[self performSelectorInBackground:@selector(loadImageArrays) withObject:nil];
...

- (void)loadImageArrays {

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

    imageArray = [[NSMutableArray alloc] init];
    for(int i = 0; i <= x; i++) {
        fileName = [NSString stringWithFormat:@"image_0000%d.png", i];
        [imageArray addObject:[UIImage imageNamed:fileName]];
    }
    [pool drain];
}

对比

NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
imageArray = [[NSArray alloc] initWithObjects:
            [UIImage imageNamed:@"image_00000.png"],
            [UIImage imageNamed:@"image_00001.png"],
            [UIImage imageNamed:@"image_0000X.png"],
                    nil];
[pool drain];

NSZombieEnabled = YES 告诉我 [UIImage retain] 在使用后一个代码片段时被发送到释放的实例。两个数组在我的 h 文件中都有 (nonatomic, retain) 属性。为什么 NSArray 不保留图像?

4

2 回答 2

4

UIImage是 UIKit 的一部分,它不是线程安全的。例如,该方法imageNamed:可能会破坏UIImage类用于缓存的全局名称-图像字典。

如果要在后台线程上加载图像,则必须使用 Core Graphics。

编辑以回答您的评论:

您可以使用以下方式加载 PNG 文件:

CGDataProviderRef source = CGDataProviderCreateWithURL((CFURLRef)url);
CGImageRef image = CGImageCreateWithPNGDataProvider(source, NULL, NO, kCGRenderingIntentDefault);
CFRelease(source);

ACGImage是核心基础对象,可以存储在NSArray. 然后,您可以从中创建一个UIImage(当然在主线程上):

[[UIImage alloc] initWithCGImage:image]
于 2010-01-26T17:03:26.120 回答
0

尽管我知道可变数组和不可变数组之间存在很大差异,但我自己对此表示怀疑。有些东西告诉我,这不仅仅是一个可变与不可变的问题。看起来你的游泳池过早地排干了(听起来很讨厌)。并不是说它应该有所作为,但是您可以尝试通过这样做来产生一个新线程吗?

[NSThread detachNewThreadSelector:@selector(loadImageArrays) toTarget:self withObject:nil];

我只是对结果很好奇..还在干净的环境中尝试这两个片段(即:周围没有其他代码)。如果您的第二个代码片段在那里工作,您应该在其他地方寻找解决方案。

于 2010-01-26T16:57:06.140 回答