我知道很多人以前都遇到过这个问题,我已经阅读了很多建议的解决方案,其中没有一个能为我解决。我正在处理一个大型项目的一部分,涉及三个不同的视图:第一个视图包含一个UITableView
,其中包含名为WeekdaySelectionWithPopoverCellController
的自定义单元格。此单元格包含指定工作日(周一至周五)的标签,UISwitch
以及根据交换机状态分别显示或隐藏的以下元素。如果开关打开,则单元格如下所示:
----------------------------------------------------------------------
| Monday [ON/off] between ( N/A ) and ( N/A ) |
----------------------------------------------------------------------
如果它关闭它看起来像这样:
----------------------------------------------------------------------
| Monday [on/OFF] |
----------------------------------------------------------------------
(N / A)元素是UIButtons。如果用户点击其中一个按钮,则会打开带有日期选择器的UIPopover
。我们的想法是用户从选择器中选择应该显示在UIButtons上的时间而不是(N / A):
----------------------------------------------------------------------
| Monday [ON/off] between ( 12:30 ) and ( 16:00 ) |
----------------------------------------------------------------------
在击中UISwitch时隐藏元素的工作方式与弹出窗口的显示一样。但是,如果用户点击弹出窗口中的“完成”按钮并且弹出窗口被解除,则应用程序崩溃并出现以下错误:
-[UITableViewCell isKindOfClass:]: message sent to deallocated instance 0xf42a100
奇怪的是,包含调用isKindOfClass的代码的唯一地方是ModalTableViewController
(弹出窗口的父视图和自定义单元格),并且显示的实例的地址不属于它。它也不是只留下自定义单元格类(WeekdaySelectionWithPopoverCellController
)的弹出窗口的地址。
让我给你ModalTableViewController.m的相关部分:
@implementation ModalTableViewController
@synthesize mtvcNavigationBar;
@synthesize mtvcTableView;
@synthesize cell;
@synthesize lable;
@synthesize button;
// WeekdaySelectionWithPopoverCell
@synthesize wswpMainLabel;
@synthesize wswpFromLabel;
@synthesize wswpToLabel;
@synthesize wswpOClockFromLabel;
@synthesize wswpOClockToLabel;
@synthesize wswpSwitch;
@synthesize wswpFromValueButton;
@synthesize wswpToValueButton;
@synthesize popoverController;
// more code...
- (ModalTableViewController *)initWithParam:(NSString *)title andData:(NSArray *)myData andSelection:(NSArray *)selection {
[self initSwipeLeftNavigation];
mtvcNavigationBar.topItem.title = title;
mtvcSectionSize = [myData count];
mtvcSectionname = @"";
mtvcLabels = myData;
mtvcData = selection;
[mtvcLabels retain];
[mtvcData retain];
[otherValues retain];
mtvSingleton = [ModalTableViewSingleton sharedInstance];
return self;
}
// more code...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cellRet;
NSString *MyIdentifier = @"WeekdaySelectionWithPopoverCellController";
cellRet = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cellRet == nil) {
[[NSBundle mainBundle] loadNibNamed:MyIdentifier owner:self options:nil];
cellRet = self.cell;
}
NSDictionary *tempValues;
tempValues = [mtvcData objectAtIndex:indexPath.row];
wswpSwitch = (UISwitch *)[cellRet viewWithTag:2];
wswpSwitch.on = [[tempValues valueForKey:@"company_id"] isKindOfClass:[NSNull class]] ? false: true;
BOOL negatedState = !wswpSwitch.on;
NSLog(@"tempValues: %@", tempValues);
lable = (UILabel *)[cellRet viewWithTag:1];
lable.text = [NSString stringWithFormat:@"%@", [tempValues valueForKey:@"short"]];
lable.font = [UIFont boldSystemFontOfSize:16];
lable = (UILabel *)[cellRet viewWithTag:3];
lable.font = [UIFont boldSystemFontOfSize:16];
lable.text = [NSString stringWithFormat:@"%@", @"von"];
lable.hidden = negatedState;
lable = (UILabel *)[cellRet viewWithTag:5];
lable.text = [NSString stringWithFormat:@"%@", @"bis"];
lable.font = [UIFont boldSystemFontOfSize:16];
lable.hidden = negatedState;
lable = (UILabel *)[cellRet viewWithTag:7];
lable.text = @"Uhr";
lable.font = [UIFont boldSystemFontOfSize:16];
lable.hidden = negatedState;
lable = (UILabel *)[cellRet viewWithTag:8];
lable.text = @"Uhr";
lable.font = [UIFont boldSystemFontOfSize:16];
lable.hidden = negatedState;
button = (UIButton *)[cellRet viewWithTag:4];
[self setButtonLabel:button forKey:@"beginning" fromDict:tempValues];
button.hidden = negatedState;
/*
if (![[tempValues valueForKey:@"beginning"] isKindOfClass:[NSNull class]]) {
button.titleLabel.text = [NSString stringWithFormat:@"%@", [tempValues valueForKey:@"beginning"]];
} else {
button.titleLabel.text = @"k.A.";
}
*/
button = (UIButton *)[cellRet viewWithTag:6];
[self setButtonLabel:button forKey:@"until" fromDict:tempValues];
button.hidden = negatedState;
/*
if (![[tempValues valueForKey:@"until"] isKindOfClass:[NSNull class]]) {
button.titleLabel.text = [NSString stringWithFormat:@"%@", [tempValues valueForKey:@"until"]];
} else {
button.titleLabel.text = @"k.A.";
}
*/
self.cell = nil;
return cellRet;
}
- (void)setButtonLabel:(UIButton *)btn forKey:(NSString *)key fromDict:(NSDictionary *)dict {
[btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
NSString *text = [dict objectForKey:key];
if ([mtvSingleton.sharedData objectForKey:key]) {
[btn setTitle:[mtvSingleton.sharedData objectForKey:key] forState:UIControlStateNormal];
} else {
if ([text isKindOfClass:[NSNull class]] ||
[text isEqualToString:@""])
{
[btn setTitle:@"k.A." forState:UIControlStateNormal];
} else {
[btn setTitle:text forState:UIControlStateNormal];
}
}
}
// more code...
- (IBAction)switchButtonValueChanged:(id)sender
{
//[self changeDisplayState:wsdSwitch.on forObj:sender];
// UISwitch *tmp = (UISwitch *)sender;
UIView *v = (UIView *)sender;
do {
v = v.superview;
} while (![v isKindOfClass:[UITableViewCell class]]);
// WeekdaySelectionWithPopoverCellController *cell1 = (WeekdaySelectionWithPopoverCellController *)v;
cell = (UITableViewCell *)v;
wswpSwitch = (UISwitch *)[cell viewWithTag:2];
BOOL negatedState = !wswpSwitch.on;
lable = (UILabel *)[cell viewWithTag:3];
lable.hidden = negatedState;
lable = (UILabel *)[cell viewWithTag:5];
lable.hidden = negatedState;
lable = (UILabel *)[cell viewWithTag:7];
lable.hidden = negatedState;
lable = (UILabel *)[cell viewWithTag:8];
lable.hidden = negatedState;
button = (UIButton *)[cell viewWithTag:4];
button.hidden = negatedState;
button = (UIButton *)[cell viewWithTag:6];
button.hidden = negatedState;
/*
wswpSwitch = (UISwitch *)[cell1 viewWithTag:2];
BOOL negatedState = !wswpSwitch.on;
lable = (UILabel *)[cell1 viewWithTag:3];
lable.hidden = negatedState;
lable = (UILabel *)[cell1 viewWithTag:5];
lable.hidden = negatedState;
lable = (UILabel *)[cell1 viewWithTag:7];
lable.hidden = negatedState;
lable = (UILabel *)[cell1 viewWithTag:8];
lable.hidden = negatedState;
button = (UIButton *)[cell1 viewWithTag:4];
button.hidden = negatedState;
button = (UIButton *)[cell1 viewWithTag:6];
button.hidden = negatedState;
*/
}
#pragma mark - handlers
- (IBAction)toButtonHandler:(id)sender {
dppvc = [[DatePickerPopoverViewController alloc] initWithCaller:self andKey:@"beginning"];
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:dppvc];
popover.delegate = self;
self.popoverController = popover;
[popover release];
[self.popoverController presentPopoverFromRect:[(UIButton *)sender frame]
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
- (IBAction)fromButtonHandler:(id)sender {
dppvc = [[DatePickerPopoverViewController alloc] initWithCaller:self andKey:@"until"];
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:dppvc];
popover.delegate = self;
self.popoverController = popover;
[popover release];
CGRect senderFrameRect = [(UIButton *)sender frame];
[self.popoverController presentPopoverFromRect:senderFrameRect
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
#pragma mark - UIPopoverControllerDelegate
//---called when the user clicks outside the popover view---
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController {
// NSLog(@"popover about to be dismissed");
return YES;
}
//---called when the popover view is dismissed---
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
// NSLog(@"popover dismissed");
}
- (void)dismissPopover {
if (popoverController != nil) {
[popoverController dismissPopoverAnimated:YES];
NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
int i;
for (i = 0; i < [mtvcLabels count]; i++) {
[indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
}
[mtvcTableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:YES];
}
}
- (void)dealloc {
[mtvcSectionname release];
[mtvcLabels release];
[mtvcData release];
[cell release];
[super dealloc];
}
崩溃发生在main.m:
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// crashes:
int retVal = UIApplicationMain(argc, argv, nil, nil); // <--
[pool release];
return retVal;
}
我已启用NSZombieEnabled
,MallocStackLoggingNoComp
和NSAutoreleaseFreedObjectCheckEnabled
但编译器不会向我提供比我发布的信息更多的信息。
我花了一整天时间试图解决这个问题,但无济于事。任何正确方向的提示都值得赞赏!
答案 0 :(得分:0)
我已经能够处理这个特殊的错误。问题是cellRet
中的cellForRowAtIndexPath
未被保留。以下代码段解决了上述错误:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cellRet;
NSString *MyIdentifier = @"WeekdaySelectionWithPopoverCellController";
cellRet = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cellRet == nil) {
[[NSBundle mainBundle] loadNibNamed:MyIdentifier owner:self options:nil];
cellRet = self.cell;
[cellRet retain];
}
// ...
}
然而,现在,我遇到了一个类似的新错误。这次它说:
*** -[CALayer release]: message sent to deallocated instance 0xc656d30
以下主题提供了有关此问题的更多信息:"[CALayer release]: message sent to deallocated instance" when dismissing modal view controller
我尝试将popover视图控制器的属性更改为assign
而不是retain
,但这又给了message sent to deallocated instance
错误,这次是对于popover视图控制器。 / p>
有人有想法吗? TIA!
答案 1 :(得分:0)
我通常处理的方法是为我的自定义单元格创建UITableViewCell的子类。并使用笔尖。我创建了一个从笔尖加载单元格的自定义init。如下。
- (id)init
{
self = [[[[NSBundle mainBundle] loadNibNamed:@"NibName" owner:self options:nil] objectAtIndex:0] retain];
if (self)
{
// any further initialization
}
return self;
}
笔尖中的将单元格的类设置为新类。
然后使用您的手机执行以下操作。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"CustomCell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[[CustomCell alloc] init] autorelease];
}
// setup your cell
return cell;
}
您绝对应该在委托属性上使用assign。