0

我正在使用 drupal-ios-sdk(基于 AFNetworking),我的应用程序有一个使用情节提要创建的选项卡栏控制器。加载其中一个视图控制器时,我正在initWithCoder使用 drupal-ios-sdk 创建一个请求,并在success block. 稍后viewDidLoad我尝试打印此变量,并且我对为什么必须在成功块中保留实例变量感兴趣,即使我使用自动释放定义了变量。

这不是ARC!

在成功块中不使用保留

我的 VC.h

@interface AboutViewController : UIViewController {
    @private
    NSDictionary *response;
    NSString *aboutPageHTML;

}
@end

我的VC.m

-(id) initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
    NSDictionary *viewData = [NSMutableDictionary new];

    [viewData setValue:@"aboutse" forKey:@"view_name"];

    aboutPageHTML = [[[NSString alloc]init] autorelease];

    void(^successBlock)(AFHTTPRequestOperation*, id) =
    ^(AFHTTPRequestOperation *operation, id responseObject) {
        response = [responseObject copy];
        aboutPageHTML = [response valueForKey:@"body"];
        NSLog(@"%s - %@", __PRETTY_FUNCTION__, aboutPageHTML);

        [aboutPageHTML retain]; // critical!

    };

    [DIOSView viewGet:viewData success:successBlock
              failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                  NSLog(@"%s, %@", __PRETTY_FUNCTION__, error);            
    }];

}
return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    NSLog(@"%s - %@", __PRETTY_FUNCTION__, aboutPageHTML);
    NSLog(@"%s - %f %f", __PRETTY_FUNCTION__, self.view.bounds.size.width, self.view.bounds.size.height);  
}

编辑:

声明变量__block似乎没有什么区别。怎么会?

4

1 回答 1

1

这段代码有很多问题。aboutPageHTML是一个您想要强引用的实例变量(即应该保留)。在aboutPageHTML = [[[NSString alloc]init] autorelease];你没有保持对它的强烈引用。这是不正确的。

稍后,在您的成功块中(它是一个块无关紧要;它只是稍后运行的任何代码),您aboutPageHTML = [response valueForKey:@"body"]; [aboutPageHTML retain];会保留存储在该实例变量中的对象。因此,您在两个地方与同一实例变量的内存管理不一致。

此外,当您将另一个值分配给强引用变量时,您应该确保释放以前的值,您没有这样做。这适用于aboutPageHTMLresponse

最后, 指向的对象viewData被泄露,因为你对它有一个强引用(你使用new)但不释放它。

此外,您应该使用setObject:forKey:objectForKey:作为字典。当你想要一个可以更改的字典时,你需要声明一个可变字典。(这可能是您(错误地)决定使用的原因setValue:forKey:

所以总而言之,这更像是:

-(id) initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
    NSMutableDictionary *viewData = [NSMutableDictionary new];

    [viewData setObject:@"aboutse" forKey:@"view_name"];

    aboutPageHTML = [[NSString alloc] init];

    void(^successBlock)(AFHTTPRequestOperation*, id) =
    ^(AFHTTPRequestOperation *operation, id responseObject) {
        [response release];
        response = [responseObject copy];
        [aboutPageHTML release];
        aboutPageHTML = [[response objectForKey:@"body"] retain];
    };

    [DIOSView viewGet:viewData success:successBlock
              failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                  NSLog(@"%s, %@", __PRETTY_FUNCTION__, error);            
    }];
    [viewData release];
}
return self;
}
于 2013-03-21T09:06:14.010 回答