【问题标题】:Can't seem to call NSInvocationOperation with an NSArray似乎无法使用 NSArray 调用 NSInvocationOperation
【发布时间】:2012-09-20 01:22:51
【问题描述】:

我正在尝试从 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 没有被调用吗?

谢谢。

【问题讨论】:

    标签: iphone uiimage nsoperationqueue nsinvocationoperation


    【解决方案1】:

    我的猜测是你没有保留你的队列。这是发生了什么

    1. 您的数组(自动释放)进入 NSInvocationOperation 并被保留(没问题)
    2. 您的NSInvocationOperation 进入队列(保留),然后被释放。这里没问题,因为保留计数仍然是 1:1 (alloc) + 1 (retain) - 1 (release) = 1 = 未释放。
    3. 您的队列已分配 (new = alloc+init),然后自动释放,但未在其他地方保留。问题来了:由于您已自动释放队列,一旦方法 LoadBackgroundImage 完成,队列的保留计数为 0 并自动释放,因此您的 Invocation 将不会被执行。

    您可以尝试从队列中删除autorelease 呼叫是否是问题所在。如果我是正确的,您的代码应该可以工作。但请注意,这不是一个好的解决方案,因为您正在失去记忆。只是看看它是否有效。

    你绝对应该创建一个类、一个单例、一个实例变量或任何你喜欢的东西来保留队列的那个实例。此外,最好只为所有 LoadBackgroundImage 调用设置一个队列,而不是每次都创建一个新队列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-28
      • 2011-09-10
      • 2022-12-16
      • 2023-02-26
      • 1970-01-01
      • 2013-05-10
      • 1970-01-01
      • 2020-06-21
      相关资源
      最近更新 更多