有人可以向我解释为什么我需要在以下代码段中保留声明吗?
我相信在学习过程中,下面的代码段对我来说不是很清楚。我知道一个alloc语句会增加保留数量,但是iOS开发的某些方面仍然让我感到困惑。有人可以向我解释为什么我需要在以下代码段中保留声明吗?
为什么在以下代码段中需要:[jokesArray retain];
?
我有一个jokesArray = [[NSArray alloc]init];
从我已经阅读的是足以保留?
有人可以用简单易懂的方式解释为什么需要保留声明吗? (否则应用程序崩溃与一个EXC_BAD_ACCESS。
我有一些善良的人们试图解释,但没有奏效。任何帮助,将不胜感激。
#import "JokesViewController.h"
@implementation JokesViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
jokesArray = [[NSArray alloc]init];
[self getJokes];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[jokesArray release];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [jokesArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[[cell textLabel]setText:[[jokesArray objectAtIndex:0]objectForKey:@"text"]];
// [[cell textLabel]setText:@"ok"];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
}
#pragma mark - Custom Functions
-(void) getJokes
{
NSURL *url = [NSURL URLWithString:@"someurl"];
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
// Use when fetching text data
NSString *responseString = [request responseString];
NSDictionary *resultsDictionary = [responseString objectFromJSONString];
jokesArray = [resultsDictionary allValues];
[jokesArray retain]; //WHY DO I NEED THIS?
[self.tableView reloadData];
NSLog(@"%@", [jokesArray description]);
// Use when fetching binary data
// NSData *responseData = [request responseData];
}];
[request setFailedBlock:^{
NSError *error = [request error];
}];
[request startAsynchronous];
}
@end
您正在泄漏,因为在这部分代码你以前的NSArray分配:
NSDictionary *resultsDictionary = [responseString objectFromJSONString];
jokesArray = [resultsDictionary allValues];
[jokesArray retain];
你正在创建一个NSDictionary和更换任何jokesArray指着指向从NSDictionary中,你刚刚创建的数据。 此外,NSDictionary返回的数据是使用便利的初始化方法创建的,这意味着它将在一段时间后发布,因此您需要保留的原因。
由于您直接修改jokesArray变量,所以在您将其替换为新对象时,先前分配的NSArray不会被释放。
不完全。 NSDictionary的allValues返回一个NSArray *。 jokesArry被设置为allValues正在创建的NSArray(正如你所说,它会在没有保留的情况下自动发布)。 –
@GrahamPerks我认为你是误解了一些东西。他没有访问财产。他直接将它分配给变量,所以jokesArray指向的任何东西都将丢失,从而留下先前分配给泄漏的NSArray。但编辑措辞使其更清晰。 – raixer
当然,你是对的;我只是说它是一个NSArray而不是NSDictionary。 –
据我所知,jokesArray并得到保留在初始化
不过,既然你有这样一行:
jokesArray = [resultsDictionary allValues];
您分配一个完整的不同对象的变量,因此你保留一个整体differen t对象。我想你会想要更类似的东西:
[jokesArray addObjectsFromArray:[resultsDictionary allValues]];
如果它是一个可变数组。如果没有,你将不得不进行新的创新。在这种情况下,我可能只会在需要时初始化jokesArray。
你有这样的:
jokesArray = [[NSArray alloc]init];
另外,你有这样的:
jokesArray = [resultsDictionary allValues];
第二个呼叫,呼叫allValues,被分配一个全新的jokesArray。你已经分配的那个现在丢失了(假设jokesArray不是保留的属性),你应该在通过allValues行重新分配之前释放它。
在allValues调用后需要'保留'的原因是allValues中分配的内存将被标记为autorelease。如果你想让这个记忆坚持下去(而且看起来如此),你需要保留它。然后,您在viewDidUnload中释放的调用将释放一些内容,并且您对jokesArray的其他引用(例如计数调用)有一些内存可供采取行动。
切换到使用保留属性将使您免于所有这些麻烦。
你是怎么声明笑话数组的? – user523234