2010-03-08 85 views
0

OK,兩天來,我一直試圖解決一個錯誤我有cellForRowAtIndex方法裏面,讓說,我有錯誤追查這種方法開始,誤差[CFDictionary圖像]或[不是類型圖像]消息發送到解除分配的實例。我知道調試標誌,NSZombie,MallocStack,和其他人,他們幫助我縮小到這種方法,爲什麼,但我不知道如何解決應用程序UI的重新設計。TableViewCell自動釋放錯誤

SO我在做什麼,以及爲這段代碼,顯示一個購買細節,其中包含項目,這些項目在自己的部分,現在當處於編輯模式,出現一個單元格在底部具有「添加新項目」標籤的項目部分,並且該按鈕將呈現添加項​​目控制器的模式視圖,項目被添加並且視圖返回到購買細節屏幕,剛剛添加的項目在上面的部分中在「添加新項」單元,這個問題時,我滾動項目部分關閉屏幕並回到視圖中的應用程序崩潰與EXC_BAD_ACCESS,甚至如果我不滾動,而是打在導航欄的後退按鈕,仍然是同樣的情況,錯誤。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = nil; 

    switch (indexPath.section) 
    { 
     case PURCHASE_SECTION: 
     { 
      static NSString *cellID = @"GenericCell"; 

      cell = [tableView dequeueReusableCellWithIdentifier:cellID]; 

      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 
               reuseIdentifier:cellID] autorelease]; 
       cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
      } 

      switch (indexPath.row) 
      { 
       case CATEGORY_ROW: 
        cell.textLabel.text   = @"Category:"; 
        cell.detailTextLabel.text = [self.purchase.category valueForKey:@"name"]; 
        cell.accessoryType   = UITableViewCellAccessoryNone; 
        cell.editingAccessoryType = UITableViewCellAccessoryDisclosureIndicator; 

        break; 
       case TYPE_ROW: 
        cell.textLabel.text   = @"Type:"; 
        cell.detailTextLabel.text = [self.purchase.type valueForKey:@"name"]; 
        cell.accessoryType   = UITableViewCellAccessoryNone; 
        cell.editingAccessoryType = UITableViewCellAccessoryDisclosureIndicator; 

        break; 
       case VENDOR_ROW: 
        cell.textLabel.text   = @"Payment:"; 
        cell.detailTextLabel.text = [self.purchase.vendor valueForKey:@"name"]; 
        cell.accessoryType   = UITableViewCellAccessoryNone; 
        cell.editingAccessoryType = UITableViewCellAccessoryDisclosureIndicator; 

        break; 
       case NOTES_ROW: 
        cell.textLabel.text   = @"Notes"; 
        cell.editingAccessoryType = UITableViewCellAccessoryNone; 

        break; 
       default: 
        break; 
      } 
      break; 
     } 
     case ITEMS_SECTION: 
     { 

      NSUInteger itemsCount = [items count]; 

      if (indexPath.row < itemsCount) 
      { 
       static NSString *itemsCellID = @"ItemsCell"; 

       cell = [tableView dequeueReusableCellWithIdentifier:itemsCellID]; 

       if (cell == nil) 
       { 
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle 
                reuseIdentifier:itemsCellID] autorelease]; 
        cell.accessoryType = UITableViewCellAccessoryNone; 
       } 

       singleItem     = [self.items objectAtIndex:indexPath.row]; 
       cell.textLabel.text   = singleItem.name; 
       cell.detailTextLabel.text = [singleItem.amount formattedDataDisplay]; 
       cell.imageView.image  = [singleItem.image image]; 

      } 
      else 
      { 
       static NSString *AddItemCellID = @"AddItemCell"; 

       cell = [tableView dequeueReusableCellWithIdentifier:AddItemCellID]; 

       if (cell == nil) 
       { 
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                reuseIdentifier:AddItemCellID] autorelease]; 
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
       } 

       cell.textLabel.text = @"Add Item"; 
      } 
      break; 
     } 
     case LOCATION_SECTION: 
     { 
      static NSString *localID = @"LocationCell"; 

      cell = [tableView dequeueReusableCellWithIdentifier:localID]; 

      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle 
               reuseIdentifier:localID] autorelease]; 
       cell.accessoryType = UITableViewCellAccessoryNone; 
      } 

      cell.textLabel.text   = @"Purchase Location"; 
      cell.accessoryType   = UITableViewCellAccessoryDisclosureIndicator; 
      cell.editingAccessoryType = UITableViewCellAccessoryNone; 
      break; 
     } 
     default: 
      break; 
    } 
    return cell; 
} 

的singleItem是模態型購買項目的核心數據

現在我知道是什麼原因造成的錯誤,怎麼解決這個問題呢,我都試過,我知道和什麼我不都有些都知道,但是,沒有任何進展,請任何建議如何解決這個沒有重新設計是我的目標,也許是一個錯誤我這樣做,我看不到,但如果它是自動釋放的性質,比我將重新設計。

更新:加入AddItemController

// 
// AddItemViewController.m 
// spendTrac 
// 
// Created by iAm on 3/5/10. 
// Copyright 2010 heariamStudios. All rights reserved. 
// 

#import "AddItemViewController.h" 
#import "Purchase.h" 
#import "PurchaseItem.h" 
#import "FormattedDataDisplay.h" 
#import "ModalAlert.h" 
#import "UtilityBelt.h" 

@implementation AddItemViewController 

@synthesize purchase, item, itemAmount, itemImage; 
@synthesize amountPadBtn, nameAlertBtn, addImageBtn; 
@synthesize amountLab, itemNameLab; 
@synthesize itemImageView; 


#pragma mark - 
#pragma mark IBAction Methods 

- (void)cancel:(id)sender 
{ 
    [self.navigationController popViewControllerAnimated:YES]; 
} 

- (void)save:(id)sender 
{ 
    NSManagedObjectContext *context = purchase.managedObjectContext; 

    if (!item) 
    { 
     itemImage = [NSEntityDescription insertNewObjectForEntityForName:@"Image"   inManagedObjectContext:context]; 
     item  = [NSEntityDescription insertNewObjectForEntityForName:@"PurchaseItem" inManagedObjectContext:context]; 
     [purchase addItemsObject:item]; 
     item.displayOrder = [NSNumber numberWithInteger:[purchase.items count]]; 

    } 


    NSString  *stringAmt = [UtilityBelt charStripper:self.amountLab.text]; 
    NSDecimalNumber *amount  = [NSDecimalNumber decimalNumberWithString:stringAmt]; 

    [itemImage setValue:self.itemImageView.image forKey:@"image"]; 

    item.image = itemImage; 
    item.name = itemNameLab.text; 
    item.amount = amount; 

    NSError *error = nil; 
    if (![context save:&error]) 
    { 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 

    [self.navigationController popViewControllerAnimated:YES]; 
} 

- (void)amountPadButtonTapped:(id)sender 
{ 
    AmountPad *amountPad = [[AmountPad alloc]initWithNibName:@"AmountPad" bundle:nil]; 
    amountPad.delegate = self; 
    [self.navigationController presentModalViewController:amountPad animated:YES]; 
    [amountPad release]; 
} 

- (void)nameAlertButtonTapped:(id)sender 
{ 
    NSString *answer = [ModalAlert ask:@"Name This Item" withTextPrompt:@"item name"]; 

    if (answer) 
    { 
     self.itemNameLab.text = [NSString stringWithFormat:@"%@", answer]; 
    } 
    else 
    { 
     [ModalAlert say:@"What, You Don't Know!"]; 
    } 
} 


- (void)photoButtonTapped:(id)sender 
{ 
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; 
    imagePicker.delegate  = self; 
    imagePicker.allowsEditing = YES; 
    imagePicker.mediaTypes  = [UIImagePickerController availableMediaTypesForSourceType:imagePicker.sourceType]; 
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) 
    { 
     imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; 
    } 
    else { 
     imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 
    } 
    [self presentModalViewController:imagePicker animated:YES]; 
    [imagePicker release]; 

} 

- (void)imagePickerController:(UIImagePickerController *)picker 
     didFinishPickingImage:(UIImage *)selectedImage 
        editingInfo:(NSDictionary *)editingInfo 
{ 
    // Create a thumbnail version of the image for the item object. 
    CGSize size = selectedImage.size; 
    CGFloat ratio = 0; 
    if (size.width > size.height) { 
     ratio = 277.3/size.width; 
    } else { 
     ratio = 277.3/size.height; 
    } 
    CGRect rect = CGRectMake(0.0, 0.0, ratio * size.width, ratio * size.height); 

    UIGraphicsBeginImageContext(rect.size); 
    [selectedImage drawInRect:rect]; 
    self.itemImageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    [self dismissModalViewControllerAnimated:YES]; 
} 


- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker 
{ 
    [self dismissModalViewControllerAnimated:YES]; 
} 

#pragma mark - 
#pragma mark View Controller Methods 

- (void)viewDidLoad 
{ 
    if (self.item) 
    { 
     self.itemImage    = self.item.image; 
     self.itemImageView.image = [self.item.image image]; 
     self.itemNameLab.text  = self.item.name; 
     self.amountLab.text   = [self.item.amount formattedDataDisplay]; 
    } 

    UINavigationItem *navigationItem = self.navigationItem; 
    navigationItem.title = @"Item"; 

    UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 
                        target:self 
                        action:@selector(cancel:)]; 
    self.navigationItem.leftBarButtonItem = cancelButton; 
    [cancelButton release]; 

    UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:@"Save" 
                    style:UIBarButtonSystemItemSave 
                    target:self 
                    action:@selector(save:)]; 
    self.navigationItem.rightBarButtonItem = saveButton; 
    [saveButton release]; 
    [super viewDidLoad]; 
} 

- (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. 
} 

- (void)viewDidUnload 
{ 
    // Release any retained subviews of the main view. 
    self.amountLab  = nil; 
    self.itemNameLab = nil; 
    self.addImageBtn = nil; 
    self.nameAlertBtn = nil; 
    self.amountPadBtn = nil; 

    [super viewDidUnload]; 
} 


#pragma mark - 
#pragma mark AmountPadDelegate Method 

- (void)amountPadDidPressDoneButton:(NSString *)amount 
{ 
    NSDecimalNumber *itemAmt = [NSDecimalNumber decimalNumberWithString:amount]; 
    self.amountLab.text = [itemAmt formattedDataDisplay]; 
    [self dismissModalViewControllerAnimated:YES]; 
} 



#pragma mark - 
#pragma mark Memory Management 

- (void)dealloc 
{ 
    [addImageBtn release]; 
    [nameAlertBtn release]; 
    [amountPadBtn release]; 

    [itemAmount  release]; 
    [purchase  release]; 
    [item   release]; 
    [itemImage  release]; 

    [itemImageView release]; 

    [amountLab  release]; 
    [itemNameLab release]; 
    [super dealloc]; 
} 


@end 
+0

請發佈整個方法。 – 2010-03-08 22:55:30

+0

確定整個方法是有 – iAm 2010-03-09 03:44:17

回答

0

看着你保存:在AddItemViewController方法,我看不出項目被保留。它是自動釋放的,所以它需要保留在某個地方。有可能是這樣的:

[purchase addItemsObject:item] 

保留它,但我必須看到該代碼。

編輯:

添加到您保存:方法:

[item retain]; 

我不明白的項目是如何保持。由於它是autoreleased項目將是一個糟糕的指針,導致你的錯誤。並且,由於您在卸載/加載視圖時以及錯誤清單本身是自己的,並且viewDidLoad:references項目,我認爲這是一個很好的可能性。我不完全確定,因爲我不知道購買的階級階層。

+0

OK,singleItem的類型是購買項目是一個coreData的實體,是的,它是PurchaseDetailController的屬性,我確實有self.singleItem,但去掉它進行測試的。我也添加了一個保留消息self.singleItem = [self.items objectAtIndex:indexPath.row] retain];但仍然是同樣的錯誤。如果您有時間查看,我可以向您發送兩個類PurchaseDetail和AddItem,請告知我 – iAm 2010-03-09 16:42:37

+0

當您添加項目時,它是否會添加到items數組中? – 2010-03-09 16:51:30

+0

只需將其他類的相關代碼添加到您的問題。 – 2010-03-09 16:59:45

0

東西有與您添加項目控制器做可能過度釋放的singleItem圖像您添加。當單元格在屏幕外滾動並被重用時,它會得到處理,然後在重新顯示時崩潰。如果這是真的,問題將出現在-cellForRowAtIndexPath:之外。

如果您沒有看到任何明顯的情況,可以使用gdb命令bt 3(或左右)將[PurchaseItem retain]和[PurchaseItem release]上的連續斷點放在一起,然後查看釋放它的內容。你可能不得不看看圖像本身的保留和釋放。

你嘗試運行靜態代碼分析,看它是否拿起一個相關的內存管理錯誤?其他

一兩件事:它似乎很奇怪的消息 - 圖像發送到圖像。 singleItem.image的類是什麼?

+0

singleItem是核心數據模型類購買項,以及「圖像」在該實體相關的屬性。我有一個名爲「Image」的實體,並且返回到PurchaseItem實體的反向關係。現在「[singleItem.image image]」返回一個UIimage,但singleItem.image返回一個「Image」類型。響應,你提到了一些我沒有嘗試的東西,我仍然是新的東西,所以我會嘗試靜態代碼分析器,看看發生了什麼。我也將數據保存到添加項目控制器中的上下文,所以我應能釋放在該控制器,是沒有 – iAm 2010-03-09 13:56:03

+0

靜態分析儀沒有返回任何問題,如果您有任何其他建議我願意,問題是在[singleItem.image圖像]調用,因爲當我離開這個那裏是沒有錯誤的,但我仍然是太新,看到的解決辦法,我會但一直走下去,去就像勁量兔子:),但我可能需要在正確的方向推;) – iAm 2010-03-09 14:42:14

+0

如何設置一個[PurchaseItem release]上的斷點,導致斷點窗口中,i我正在使用一個符號,它是灰色的,這個消息[PurchaseItem版本]不在我的代碼中。那麼怎麼做測試,看看當它被稱爲 – iAm 2010-03-09 16:07:38