iOS - 无法在 didSelectRowAtIndexPath 中访问 NSMutableArray?
我无法在 didSelectRowAtIndexPath
中访问我的 NSMutableArray,尽管我可以在 cellForRowAtIndexPath
中访问它。
这是我的代码:-
- (void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"drinks" ofType:@"plist"];
self.drinkArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSLog(@"%@", self.drinkArray);
[super viewDidLoad];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
NSLog(@"I am inside cellForRowAtIndexPath");
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
NSDictionary *dict = [self.drinkArray objectAtIndex:indexPath.row];
cell.textLabel.text = [dict objectForKey:@"name"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
[dict release];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DrinkDetails *detailViewController = [[DrinkDetails alloc] initWithNibName:@"DrinkDetails" bundle:nil];
// ...
// Pass the selected object to the new view controller.
//detailViewController.drink = [self.drinkArray objectAtIndex:indexPath.row];
NSLog(@"%@", self.drinkArray);
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
有时 NSLog 会打印一些愚蠢的输出,有时它会给我一个错误“EXC_BAD_ACCESS”。
请看一下我的代码有什么问题。
任何帮助将不胜感激。
谢谢。
I am unable to access my NSMutableArray in didSelectRowAtIndexPath
although i am able to access it in cellForRowAtIndexPath
.
Here is my code :-
- (void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"drinks" ofType:@"plist"];
self.drinkArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSLog(@"%@", self.drinkArray);
[super viewDidLoad];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
NSLog(@"I am inside cellForRowAtIndexPath");
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
NSDictionary *dict = [self.drinkArray objectAtIndex:indexPath.row];
cell.textLabel.text = [dict objectForKey:@"name"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
[dict release];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DrinkDetails *detailViewController = [[DrinkDetails alloc] initWithNibName:@"DrinkDetails" bundle:nil];
// ...
// Pass the selected object to the new view controller.
//detailViewController.drink = [self.drinkArray objectAtIndex:indexPath.row];
NSLog(@"%@", self.drinkArray);
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
Sometime NSLog prints some stupid output and sometime it gives me an error "EXC_BAD_ACCESS".
Please take a look and check what is wrong with my code.
Any help would be appreciated.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您有一个(实际上是两个)问题,但主要问题在您的
-cellForRowAtIndexPath:
方法中:去掉这一行,它应该可以正常工作。
这解决了您的问题的原因是因为
-objectAtIndex:
只是返回一个指向内存中所请求对象的指针,因此您不会(也不应该)发送-release
消息到该对象,因为NSArray
在插入该对象时获得了该对象的所有权。向此对象引用发送-release
可以有效地释放内存中的对象,现在NSArray
中的该索引指向垃圾内存。 BAD BAD BAD另一个问题是这里存在内存泄漏:
您正在通过发送方式将
-retain
消息发送到您已经拥有所有权的对象引用-分配
。 (当然,假设您的@property
具有retain
setter 修饰符)要解决此问题,只需将
-autorelease
消息发送到此实例:You have one (really two) issues, but the main one is in your
-cellForRowAtIndexPath:
method:Get rid of this line and it should work just fine.
The reason why this fixes your issue is because
-objectAtIndex:
simply returns a pointer to the requested object in memory, therefore you do not (and should not) send the-release
message to that object because theNSArray
obtained ownership of the object when it was inserted. Sending-release
to this object reference effectively deallocates the object in memory and now this indice in theNSArray
is pointing to garbage memory. BAD BAD BADThe other issue is that you have a memory leak here:
You are sending the
-retain
message to an object reference that you already have ownership of by way of sending-alloc
. (This of course assumes that your@property
has theretain
setter modifier)To fix this issue, simply send the
-autorelease
message to this instance:不要释放对象,除非该对象是使用
alloc
创建的,或者是通过以new
或copy
开头的方法获取的,或者显式retain< /代码>'ed。 (NARC)
在这种情况下:
NSDictionary *dict = [self.drinkArray objectAtIndex:indexPath.row];
未归还保留,因此您不拥有所有权,不应释放它。
出于同样的原因:
已分配,因此需要使用 convince 方法释放或获取它,该方法将返回自动释放的对象:
Don't release an object unless it was created with
alloc
or obtained with a method beginning withnew
orcopy
or explicitlyretain
'ed. (NARC)In this case:
NSDictionary *dict = [self.drinkArray objectAtIndex:indexPath.row];
was not returned retained so you do not have ownership and should not release it.
By the same token:
is alloc'ed so it needs to be released or obtained with a convince method that will return an autoreleased object:
您不应该在
cellForRowAtIndexPath
中[dict release]
。objectAtIndex
不会保留它,因此当您释放它时,它可能会被从数组中清除。You shouldn't
[dict release]
incellForRowAtIndexPath
.objectAtIndex
does not retain it, so it may be sweeped out of your array when you release it.