2

我似乎有一个指针问题,我似乎无法修复它。有人可以帮我吗?

-(void) connectionDidFinishLoading:(NSURLConnection *)connection{
    NSLog(@"Finished Downloading Image: %@" ,[connection.originalRequest.URL absoluteString]);
    UIImage *CompiledImage=[UIImage imageWithData:ImageData];
    SEL selector=@selector(ImageDownloadingCompleted:Image:);
    if([[self Delegate] respondsToSelector:selector]){
        [[self Delegate] ImageDownloadingCompleted:self Image:CompiledImage];
    }
    else{
        if(Target){
            *Target=CompiledImage;
        }
    }
    // NSLog(@"Image Size:%i", [ImageData length]);
}

Target是类型的私有变量UIImage(声明为UIImage *Target;:) CompiledImage也是 a UIImage。我想要做的是将目标地址的内容设置为 CompiledTarget 的内容。这会导致以下错误:

从不兼容的类型“UIImage *__strong”分配给“UIImage”

我试过 :

memccpy(__bridge Target, &CompiledImage, sizeof(Target),sizeof(Target));

我得到这个错误:

预期表达

4

3 回答 3

5

您只需将其设置为,

Target = CompiledImage;

不需要*。由于两者都是指针,因此如果您使用上述代码,您基本上是在分配内存地址而不是复制内容。

附带说明,请以小写字母开头的变量名。Target通常代表一个类名。根据苹果编码约定,它应该是target.

根据您的评论,您可以执行以下操作,

在 ViewController 类中,将 a 声明UIImage@property

@property (nonatomic, retain) UIImage *downloadedImage;

在进行 URL 调用时,

NSImageLoader *imageLoader = [[NSImageLoader alloc] init];
[imageLoader setTarget:self];//setting current viewController as target instead of UIImage

下载图片时,

-(void) connectionDidFinishLoading:(NSURLConnection *)connection{
    NSLog(@"Finished Downloading Image: %@" ,[connection.originalRequest.URL absoluteString]);
    UIImage *CompiledImage=[UIImage imageWithData:ImageData];
    SEL selector=@selector(ImageDownloadingCompleted:Image:);
    if([[self Delegate] respondsToSelector:selector]){
        [[self Delegate] ImageDownloadingCompleted:self Image:CompiledImage];
    }
    else{
        if(Target){
            Target.downloadedImage = CompiledImage;//or [Target setDownloadedImage:CompiledImage];
        }
    }
    // NSLog(@"Image Size:%i", [ImageData length]);
}

在您的 ViewController 类中,现在您可以访问图像,self.downloadedImageCompiledImage与指向相同位置的相同内存地址相同。

另一种方法是UIImage *TargetUIImage **Target你的NSImageLoader类中声明。在调用setTarget方法时,使用[imageLoader setTarget:&Target];. 在此方法中,您需要将目标设置为Target = Target;

更新: 根据您的评论,它应该是这样的,

for( NSDictionary *CurrentActivity in [Profile UserActivities]) {
        ...
        UIImage *WineImage = [UIImage imageNamed:@"loader.gif"];
        NSImageLoader *loader=[[NSImageLoader alloc] initWithURLString:[NSString stringWithFormat:@"%@%@",[TempSettings URL],[CurrentActivity objectForKey:@"ImageURL"]]];
        [loader setTarget:&WineImage];
        [loader startDownloading];
        [self addSubview:Activity];
        Counter++;
    }

然后在 NSImageLoader.h 文件@interface 中,

 __strong UIImage **Target; //This should be strong not autoreleasing

在 NSImageLoader.m 文件中,

- (void)setTarget:(UIImage *__strong *)iTarget{ //change here also
     Target = target; 
} 


-(void) connectionDidFinishLoading:(NSURLConnection *)connection{
    NSLog(@"Finished Downloading Image: %@" ,[connection.originalRequest.URL absoluteString]);
    UIImage *CompiledImage=[UIImage imageWithData:ImageData];
    SEL selector=@selector(ImageDownloadingCompleted:Image:);
    if([[self Delegate] respondsToSelector:selector]){
        [[self Delegate] ImageDownloadingCompleted:self Image:CompiledImage];
    }
    else{
        if(Target){
            *Target = CompiledImage;
        }
    }
    // NSLog(@"Image Size:%i", [ImageData length]);
}

更新2:

使用传递 UIImageView 的方法,您可以执行以下操作,

    for( NSDictionary *CurrentActivity in [Profile UserActivities]) {
        ...
        UIImage *WineImage = [UIImage imageNamed:@"loader.gif"];
        NSImageLoader *loader=[[NSImageLoader alloc] initWithURLString:[NSString stringWithFormat:@"%@%@",[TempSettings URL],[CurrentActivity objectForKey:@"ImageURL"]]];
        [loader setTarget:Activity];//pass imageview and let the delegate method set image
        [loader startDownloading];
        [self addSubview:Activity];
        Counter++;
    }

-(void) connectionDidFinishLoading:(NSURLConnection *)connection{
    NSLog(@"Finished Downloading Image: %@" ,[connection.originalRequest.URL absoluteString]);
    UIImage *CompiledImage=[UIImage imageWithData:ImageData];
    SEL selector=@selector(ImageDownloadingCompleted:Image:);
    if([[self Delegate] respondsToSelector:selector]){
        [[self Delegate] ImageDownloadingCompleted:self Image:CompiledImage];
    }
    else{
        if(Target){
            Target.image = CompiledImage;
        }
    }
    // NSLog(@"Image Size:%i", [ImageData length]);
}

在这里传递 imageview 并让委托方法在您下载图像后设置图像。

于 2012-12-09T12:07:36.720 回答
1

使目标是 pTarget?一个指向指针的指针那么它是有意义的 *pTarget = compiledImage (因为它经常用 NSErrors 完成.. 例如在核心数据中)

你不能只是 memcpy 的东西,因为目标没有在堆上分配正确的大小。


您无法复制内存中的真实 UIImage 字节,因为您不知道这和实现细节。你甚至不知道它有多大!

但是您可以将指针复制到图像 - 它的内存地址


UIImage *pointer1 = [UIImage imageWithFoo];
UUImage *pointer2 = pointer1;

现在您还可以声明一个空指针并稍后填充

UIImage *target = nil;
UIImage *pointer1 = [UIImage imageWithFoo];
target = pointer1;

到目前为止一切都很好但是如果你想将目标传递给一个函数并且应该填充它呢?

target = [self calculateImage];

但现在你在异步函数中拥有它

[self asyncCalculateImage:&target]; // you pass it a POINTER to the POINTER to fill :)
...
- (void)asyncCalculateImage:(UIImage**)pTarget {
    UIImage *pointer1 = [UIImage imageWithFoo];
    *pTarget = pointer1; //DEREFERENCE and fill pTarget
}
于 2012-12-09T20:13:58.967 回答
0

怎么又放*了,这里CompiledImage本身就是一个指针。

只需使用Target=CompiledImage;

于 2012-12-09T12:08:24.350 回答