Iphone Can';我不想用NSArray调用NSInvocationOperation

Iphone Can';我不想用NSArray调用NSInvocationOperation,iphone,uiimage,nsoperationqueue,nsinvocationoperation,Iphone,Uiimage,Nsoperationqueue,Nsinvocationoperation,我正在尝试从url加载背景中的图像。如果我只通过了NSUrl,那么代码就非常有效。如果我尝试通过附加变量传递NSArray,它将永远不会被调用: - (void)LoadBackgroundImage: (char*)pImageURL :(int)textureID :(int)textureType { printf( "LoadBackgroundImage( %s, %d, %d)\n", pImageURL, textureID, textureType ); NS

我正在尝试从url加载背景中的图像。如果我只通过了NSUrl,那么代码就非常有效。如果我尝试通过附加变量传递NSArray,它将永远不会被调用:

- (void)LoadBackgroundImage: (char*)pImageURL :(int)textureID :(int)textureType
{

    printf( "LoadBackgroundImage( %s, %d, %d)\n", pImageURL, textureID, textureType );

    NSString* pImageURLString = [NSString stringWithFormat:@"%s", pImageURL];

    NSArray* pUrlAndReferences = [[[NSArray alloc] initWithObjects: pImageURLString, textureID, textureType, nil] autorelease];

    NSOperationQueue *queue = [[NSOperationQueue new] autorelease];
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]
                                    initWithTarget:self
                                    selector:@selector(LoadImage:)
                                    object:pUrlAndReferences];

    [queue addOperation:operation];
    [operation release];
}


- (void)LoadImage: (NSArray*)pUrlAndReferences
{
    NSString* pImageUrl = [pUrlAndReferences objectAtIndex: 0];
    int textureId = [ [ pUrlAndReferences objectAtIndex: 1 ] intValue ];
    int textureType = [ [ pUrlAndReferences objectAtIndex: 2 ] intValue ];

    NSLog( @"\n\nLoadImage: %@, %d, %d\n", pImageUrl, textureId, textureType );

    NSData* pImageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:pImageUrl]];
    UIImage* pImage = [[[UIImage alloc] initWithData:pImageData] autorelease];

    NSArray* pImageAndReferences = [[[NSArray alloc] initWithObjects: pImage, textureId, textureType, nil] autorelease];

    [pImageData release];
    [self performSelectorOnMainThread:@selector(ImageLoaded:) withObject:pImageAndReferences waitUntilDone:NO];
}
这段代码非常好用,LoadImage2被调用,而LoadImage2又很好地调用了ImageLoaded2

- (void)LoadBackgroundImage2: (char*)pImageURL
{

    NSString* pImageURLString = [NSString stringWithFormat:@"%s", pImageURL];

    NSLog( @"LoadBackgroundImage2: %@", pImageURLString );

    NSOperationQueue *queue = [NSOperationQueue new];
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]
                                    initWithTarget:self
                                    selector:@selector(LoadImage2:)
                                    object:pImageURLString];
    [queue addOperation:operation];
    [operation release];
}


- (void)LoadImage2: (NSString*)pImageURL
{
    NSLog( @"LoadImage2: %@", pImageURL );

    NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:pImageURL]];
    UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease];
    [imageData release];
    [self performSelectorOnMainThread:@selector(ImageLoaded2:) withObject:image waitUntilDone:NO];
}
此代码不起作用。LoadImage从未被调用:

- (void)LoadBackgroundImage: (char*)pImageURL :(int)textureID :(int)textureType
{

    printf( "LoadBackgroundImage( %s, %d, %d)\n", pImageURL, textureID, textureType );

    NSString* pImageURLString = [NSString stringWithFormat:@"%s", pImageURL];

    NSArray* pUrlAndReferences = [[[NSArray alloc] initWithObjects: pImageURLString, textureID, textureType, nil] autorelease];

    NSOperationQueue *queue = [[NSOperationQueue new] autorelease];
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]
                                    initWithTarget:self
                                    selector:@selector(LoadImage:)
                                    object:pUrlAndReferences];

    [queue addOperation:operation];
    [operation release];
}


- (void)LoadImage: (NSArray*)pUrlAndReferences
{
    NSString* pImageUrl = [pUrlAndReferences objectAtIndex: 0];
    int textureId = [ [ pUrlAndReferences objectAtIndex: 1 ] intValue ];
    int textureType = [ [ pUrlAndReferences objectAtIndex: 2 ] intValue ];

    NSLog( @"\n\nLoadImage: %@, %d, %d\n", pImageUrl, textureId, textureType );

    NSData* pImageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:pImageUrl]];
    UIImage* pImage = [[[UIImage alloc] initWithData:pImageData] autorelease];

    NSArray* pImageAndReferences = [[[NSArray alloc] initWithObjects: pImage, textureId, textureType, nil] autorelease];

    [pImageData release];
    [self performSelectorOnMainThread:@selector(ImageLoaded:) withObject:pImageAndReferences waitUntilDone:NO];
}
有人知道为什么LoadImage没有被调用吗


谢谢。

我猜你没有排队。下面是发生的事情

  • 您的阵列(自动释放)进入
    NSInvocationOperation
    并被保留(没问题)
  • 您的
    NSInvocationOperation
    进入队列(保留),然后释放。这里没有问题,因为保留计数仍然是1:1(
    alloc
    )+1(
    retain
    )-1(
    release
    )=1=未解除分配
  • 您的队列已分配(
    new
    =
    alloc
    +
    init
    ),然后自动删除,但不会保留在其他位置。问题来了:因为您已经自动删除了队列,一旦方法
    LoadBackgroundImage
    完成,队列的保留计数为0,并且它会自动释放,因此,您的调用将不会执行
  • 如果这是问题所在,您可以从队列中删除
    autorelease
    调用。如果我是对的,你的代码应该可以工作。但是请注意,这不是一个好的解决方案,因为你正在失去记忆。只是看看它是否有效

    您应该创建一个类、一个单例、一个实例变量或任何您想要保留队列实例的东西。另外,对于所有
    LoadBackgroundImage
    调用,最好只有一个队列,而不是每次都创建一个新队列