2

URLから背景の画像を読み込もうとしています。私が渡すのがNSUrlだけであれば、コードはうまく機能します。追加の変数を使用してNSArrayを渡そうとすると、呼び出されません。

このコードはうまく機能し、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が呼び出されない理由を誰かが知っていますか?

ありがとう。

4

1 に答える 1

1

私の推測では、あなたはあなたのキューを保持していません。これが起こっていることです

  1. アレイ(自動解放)がになり、NSInvocationOperation保持されます(問題ありません)
  2. あなたNSInvocationOperationはキューに入り(保持され)、その後解放されます。保持カウントはまだ1であるため、ここでは問題ありません:1(alloc)+ 1(retain)-1(release)=1=割り当て解除されていません。
  3. キューは割り当てられ(new= alloc+ init)、その後自動解放されますが、他の場所には保持されていません。ここで問題が発生します。キューを自動解放したため、メソッドLoadBackgroundImageが終了すると、キューの保持カウントは0になり、自動的に解放されるため、呼び出しは実行されません。

autoreleaseキューから呼び出しを削除するだけで、それが問題であるかどうかを試すことができます。私が正しければ、あなたのコードは機能するはずです。しかし、あなたは記憶を失っているので、それは良い解決策ではないことに注意してください。それが機能するかどうかを確認するだけです。

クラス、シングルトン、インスタンス変数、またはキューのそのインスタンスを保持したいものは必ず作成する必要があります。また、LoadBackgroundImage毎回新しいキューを作成するのではなく、すべての呼び出しに対して1つのキューのみを用意することをお勧めします。

于 2012-11-01T12:05:35.660 に答える