Iphone 访问块内的实例变量

Iphone 访问块内的实例变量,iphone,objective-c,ios,ipad,ios5,Iphone,Objective C,Ios,Ipad,Ios5,我有一个关于在类似我的情况下使用异步块的最佳实践的问题 例如,我有两个控制器:(设为controller1和controller2) 我把控制器2推到控制器1内: controller2 * c = [[controller2 alloc] init]; [self.navigationController pushViewController:c animated:YES]; [c release]; controller2有一个实例变量: @interface controller2 :

我有一个关于在类似我的情况下使用异步块的最佳实践的问题

例如,我有两个控制器:(设为controller1和controller2)

我把控制器2推到控制器1内:

controller2 * c = [[controller2 alloc] init];
[self.navigationController pushViewController:c animated:YES];
[c release];
controller2有一个实例变量:

@interface controller2 : UITableViewController{
    UIImageView * imageView;
}
分配并释放它:

- (id)init{
   ...
   imageView = [[UIImageView alloc] init];
   ...
}

- (void)dealloc{
   [imageView release];
   [super dealloc];
}
然后controller2下载此imageView的图像:

- (void)viewDidLoad{
 ...

[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:
    ^(NSURLResponse *response, NSData *data, NSError *error) {
        UIImage * image = [[UIImage alloc] initWithData:data scale:[[UIScreen mainScreen] scale]];
        imageView.image = image; 
        [image release];    
    }];
 }
显然,用户可以按下导航栏顶部的“后退”按钮,我们的控制器2的对象将与此图像视图一起释放

情况:

  • 下载开始

  • 控制器弹出(用户按下“后退”按钮)

  • 下载结束,imageView.image=图像导致(?)EXC\u错误访问(因为imageView已发布)

那么,我应该怎么做才能让代码更酷呢? 我喜欢积木!与NSURLConnection委托相比,它非常有趣,代码/类更少

  • 块是否保留了实例变量?(:OOO)

  • 也许我应该在块之前保留我的实例变量,然后在块中释放它?(我觉得这很傻)

那么,使用这些块的最佳实践是什么? 也许我不应该在这种情况下使用块来改进代码

p、 s:我尝试过这样做:将NSOperationQueue作为实例变量,并停止dealloc中的所有任务。。但这扼杀了这一区块的优势:( 在这种情况下,最好将我的downloader类与delegate一起使用;(无论如何,代码太多了)

p、 附言: 我知道我应该停止下载后弹出我的控制器,但我不是关于它。 让它成为无论如何都应该完成的任何任务(例如,转换视频等,任何“沉重”的背景线程),即使用户离开了这个控制器,但如果它们是活动的,它将使用一些实例变量


谢谢你

我认为你的块方法很好。我认为是内存管理让你明白了:为什么controller2在它的dealoc方法中解除了imageView的锁定。这应该是

[imageView release];
不解除锁定。controller2是否保留该图像视图

这将起作用的原因是NSURLConnection block将捕获imageView,因此即使在controller2消失后它仍会挂起。如果按back键,控制器将消失,imageView将获得一个新图像,然后它也将消失。一切都应该正常


我同意你的观点,块是很好的。另一个很好的东西是ARC,两者配合得很好。你能在这个项目中使用ARC吗?

你应该声明你的变量:

    __block UIImageView*imageView;
第一个块开始[self-retainCount]=2,[imagesDictionary retainCount]=1

第二个块开始[self-retainCount]=2,[imagesDictionary retainCount]=1

看起来block正在保留“自我”,并在最后释放它 因此,“self”(我的实例)不能在块结束之前解除分配

这就是答案,嗯? 希望如此


谢谢

啊,当然很抱歉发布了:)那不是复制粘贴。更正了。谢谢你的回答:)但这不是一个问题,这只是这个主题中的一个输入错误。
[NSURLConnection sendAsynchronousRequest:request queue:imageDownloadersQueue completionHandler:^(NSURLResponse *response, NSData *firstImageData, NSError *error) {
        NSLog(@"first block beginning [self retainCount] = %d, [imagesDictionary retainCount] = %d",[self retainCount], [imagesDictionary retainCount]);

        NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
        UIImage * first_image = [[[UIImage alloc] initWithData:firstImageData scale:[[UIScreen mainScreen] scale]] autorelease];
        [NSURLConnection sendAsynchronousRequest:request queue:imageDownloadersQueue completionHandler:^(NSURLResponse *response, NSData *secondImageData, NSError *error) {
            NSLog(@"second block beginning  [self retainCount] = %d, [imagesDictionary retainCount] = %d",[self retainCount], [imagesDictionary retainCount]);
            UIImage * second_image = [[[UIImage alloc] initWithData:secondImageData scale:[[UIScreen mainScreen] scale]] autorelease];
            if(first_image && second_image){
                [imagesDictionary setObject:[NSArray arrayWithObjects:first_image, second_image, nil] forKey:match.match_id];
            }            
        }];
    }];