阻止iOS执行并分配变量 [英] block execution iOS and assigning variable
问题描述
我正在使用drupal-ios-sdk(基于AFNetworking),并且我的应用程序具有使用情节提要创建的标签栏控制器.当加载一个视图控制器时,我正在使用drupal-ios-sdk在initWithCoder
中创建一个请求,并在success block
中分配一个实例变量.稍后在viewDidLoad
中,我尝试打印此变量,并且我对为什么必须将实例变量保留在成功块中感兴趣,即使我使用autorelease定义了该变量也是如此.
I am using the drupal-ios-sdk (based on AFNetworking) and my app has a Tab Bar Controller created with storyboard. When loading one of the view controllers I am creating a request in initWithCoder
with drupal-ios-sdk and assigning an instance variable in the success block
. Later in viewDidLoad
I try to print this variable and I'm interested in why I have to retain the instance variable in the success block, even if I define the variable with autorelease.
这不是ARC!
@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
声明变量似乎没有什么不同.怎么会来?
declaring the variable with __block
does not seem to make a difference. How come?
推荐答案
此代码有很多错误. aboutPageHTML
是您要强引用的实例变量(即应保留).在aboutPageHTML = [[[NSString alloc]init] autorelease];
中,您并没有对其进行严格引用.这是不正确的.
There are many things wrong with this code. aboutPageHTML
is an instance variable that you want a strong reference to (i.e. should be retained). In aboutPageHTML = [[[NSString alloc]init] autorelease];
you are not maintaining a strong reference to it. This is incorrect.
然后,在您的成功块中(与它是无关紧要的;它只是稍后运行的任何代码),您执行aboutPageHTML = [response valueForKey:@"body"]; [aboutPageHTML retain];
确实保留了存储在该实例变量中的对象.因此,您在两个地方都与同一个实例变量的内存管理不一致.
And later on, in your success block (it is irrelevant that it is a block; it's just any code that runs later), you do aboutPageHTML = [response valueForKey:@"body"]; [aboutPageHTML retain];
which does retain the object stored in that instance variable. So you are being inconsistent with the memory management for the same instance variable in two places.
此外,当您将另一个值分配给强引用变量时,您应确保释放先前没有使用的值. aboutPageHTML
和response
都适用.
Also, when you assign another value to a strongly-referenced variable, you should make sure to release the previous value, which you are not doing. This goes for both aboutPageHTML
and response
.
最后,viewData
指向的对象被泄漏,因为您对其有很强的引用(使用new
),但不要释放它.
Finally, the object pointed to by viewData
is leaked, as you have a strong reference to it (you use new
) but don't release it.
此外,还应该将setObject:forKey:
和objectForKey:
用于字典.而且,当您想更改字典时,需要声明一个可变字典. (这可能就是您(错误地)决定使用setValue:forKey:
的原因)
Also, you should use setObject:forKey:
and objectForKey:
for dictionaries. And you need to declare a mutable dictionary when you want a dictionary you can change. (This is probably why you (incorrectly) decided to use setValue:forKey:
)
因此,总而言之,它会像这样:
So in conclusion, this would be more like it:
-(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;
}
这篇关于阻止iOS执行并分配变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!