Cocoa touch 使用initWithObjects将图像加载到NSArray会崩溃,但不使用NSMutableArray?

Cocoa touch 使用initWithObjects将图像加载到NSArray会崩溃,但不使用NSMutableArray?,cocoa-touch,multithreading,exc-bad-access,nsautoreleasepool,Cocoa Touch,Multithreading,Exc Bad Access,Nsautoreleasepool,当应用程序加载后,我正在将图像延迟加载到数组中。我曾经尝试过使用NSMutableArray和NSArray(一旦创建了数组,我就不需要修改它),但后者在我身上崩溃了 ... [self performSelectorInBackground:@selector(loadImageArrays) withObject:nil]; ... - (void)loadImageArrays { NSAutoreleasePool *pool; pool = [[NSAutorele

当应用程序加载后,我正在将图像延迟加载到数组中。我曾经尝试过使用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];
}
NSZombieEnabled=YES告诉我在使用后一个代码段时,[UIImage retain]被发送到了解除分配的实例。
这两个数组在我的h文件中都有(非原子,保留)属性。为什么NSArray没有保留图像?

虽然我知道可变数组和不可变数组之间有很大的区别,但我自己也有疑问。有些东西告诉我,这不是一个纯粹的可变与不变的问题。看起来你的游泳池被提前排干了(听起来很恶心)。这并不是说它会有什么不同,但你可以尝试通过这样做来产生一个新的线程

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

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

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

如果要在后台线程上加载图像,必须使用核心图形

编辑回答您的评论:

您可以通过以下方式加载PNG文件:

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

A<代码> CGImage <代码>是一个核心基础对象,可以存储在<代码> NSArray < /代码>中。然后,您可以从中生成

UIImage
(当然是在主线程上):


虽然我很欣赏你的回答,但如果我想用核心图形在背景线程中加载图像,我会怎么做呢?因此,如果一个答案让你有更多的问题,你应该写一篇新文章。对不起。不过,答案很好。非常感谢你!太好了,我不知道。。好吧,至少我有一部分是对的:-)但是,不变和可变与这个问题有什么关系?还是那只是随机行为?
CGDataProviderRef source = CGDataProviderCreateWithURL((CFURLRef)url);
CGImageRef image = CGImageCreateWithPNGDataProvider(source, NULL, NO, kCGRenderingIntentDefault);
CFRelease(source);
[[UIImage alloc] initWithCGImage:image]