2011-02-22 175 views
0

開發iOS應用程序。我有一個對象類Product.h和.m分別與我的選擇器類一起實現我的車輛選擇以匹配產品和車輛。該文件將自定義對象添加到NSMutableArray

product.h

#import <Foundation/Foundation.h> 


@interface Product : NSObject { 

} 

@property (nonatomic, retain) NSString *iProductID; 
@property (nonatomic, retain) NSString *vchProductCode; 
@property (nonatomic, retain) NSString *vchPriceCode; 
@property (nonatomic, retain) NSString *vchHitchUPC; 
@property (nonatomic, retain) NSString *mHitchList; 
@property (nonatomic, retain) NSString *mHitchMap; 
@property (nonatomic, retain) NSString *fShippingWeight; 
@property (nonatomic, retain) NSString *vchWC; 
@property (nonatomic, retain) NSString *vchCapacity; 
@property (nonatomic, retain) NSString *txtNote1; 
@property (nonatomic, retain) NSString *txtNote2; 
@property (nonatomic, retain) NSString *txtNote3; 
@property (nonatomic, retain) NSString *txtNote4; 
@property (nonatomic, retain) NSString *vchDrilling; 
@property (nonatomic, retain) NSString *vchUPCList; 
@property (nonatomic, retain) NSString *vchExposed; 
@property (nonatomic, retain) NSString *vchShortDesc; 
@property (nonatomic, retain) NSString *iVehicleID; 
@property (nonatomic, retain) NSString *iProductClassID; 
@property (nonatomic, retain) NSString *dtDateMod; 
@property (nonatomic, retain) NSString *txtBullet1; 
@property (nonatomic, retain) NSString *txtBullet2; 
@property (nonatomic, retain) NSString *txtBullet3; 
@property (nonatomic, retain) NSString *txtBullet4; 
@property (nonatomic, retain) NSString *txtBullet5; 
@property (nonatomic, retain) NSString *iUniqueIdentifier; 
@property (nonatomic, retain) NSString *dtDateLastTouched; 
@property (nonatomic, retain) NSString *txtNote6; 
@property (nonatomic, retain) NSString *InstallTime; 
@property (nonatomic, retain) NSString *SGID; 
@property (nonatomic, retain) NSString *CURTID; 
@property (nonatomic, retain) NSString *SGRetail; 
@property (nonatomic, retain) NSString *SGMemPrice; 
@property (nonatomic, retain) NSString *InstallSheet; 
@property (nonatomic, retain) NSString *mHitchJobber; 
@property (nonatomic, retain) NSString *CatID; 
@property (nonatomic, retain) NSString *ParentID; 

-(id) initWithDict:(NSDictionary *)dic; 

-(NSString *) description; 

@end 

產品執行的.m

#import "Product.h" 


@implementation Product 

@synthesize iProductID; 
@synthesize vchProductCode; 
@synthesize vchPriceCode; 
@synthesize vchHitchUPC; 
@synthesize mHitchList; 
@synthesize mHitchMap; 
@synthesize fShippingWeight; 
@synthesize vchWC; 
@synthesize vchCapacity; 
@synthesize txtNote1; 
@synthesize txtNote2; 
@synthesize txtNote3; 
@synthesize txtNote4; 
@synthesize vchDrilling; 
@synthesize vchUPCList; 
@synthesize vchExposed; 
@synthesize vchShortDesc; 
@synthesize iVehicleID; 
@synthesize iProductClassID; 
@synthesize dtDateMod; 
@synthesize txtBullet1; 
@synthesize txtBullet2; 
@synthesize txtBullet3; 
@synthesize txtBullet4; 
@synthesize txtBullet5; 
@synthesize iUniqueIdentifier; 
@synthesize dtDateLastTouched; 
@synthesize txtNote6; 
@synthesize InstallTime; 
@synthesize SGID; 
@synthesize CURTID; 
@synthesize SGRetail; 
@synthesize SGMemPrice; 
@synthesize InstallSheet; 
@synthesize mHitchJobber; 
@synthesize CatID; 
@synthesize ParentID; 

-(id) initWithDict:(NSDictionary *)dic 
{ 
    [super init]; 
    //Initialize all variables 
    self.iProductID = [[NSString alloc] initWithString:[dic objectForKey:@"iProductID"]]; 

    self.vchProductCode = [[NSString alloc] initWithString:[dic objectForKey:@"vchProductCode"]]; 

    self.vchPriceCode = [[NSString alloc] initWithString:[dic objectForKey:@"vchPriceCode"]]; 

    self.vchHitchUPC = [[NSString alloc] initWithString:[dic objectForKey:@"vchHitchUPC"]]; 

    self.mHitchList = [[NSString alloc] initWithString:[dic objectForKey:@"mHitchList"]]; 

    self.mHitchMap = [[NSString alloc] initWithString:[dic objectForKey:@"mHitchMap"]]; 

    self.fShippingWeight = [[NSString alloc] initWithString:[dic objectForKey:@"fShippingWeight"]]; 

    self.vchWC = [[NSString alloc] initWithString:[dic objectForKey:@"vchWC"]]; 

    self.vchCapacity = [[NSString alloc] initWithString:[dic objectForKey:@"vchCapacity"]]; 

    self.txtNote1 = [[NSString alloc] initWithString:[dic objectForKey:@"txtNote1"]]; 

    self.txtNote2 = [[NSString alloc] initWithString:[dic objectForKey:@"txtNote2"]]; 

    self.txtNote3 = [[NSString alloc] initWithString:[dic objectForKey:@"txtNote3"]]; 

    self.txtNote4 = [[NSString alloc] initWithString:[dic objectForKey:@"txtNote4"]]; 

    self.vchDrilling = [[NSString alloc] initWithString:[dic objectForKey:@"vchDrilling"]]; 

    self.vchUPCList = [[NSString alloc] initWithString:[dic objectForKey:@"vchUPCList"]]; 

    self.vchExposed = [[NSString alloc] initWithString:[dic objectForKey:@"vchExposed"]]; 

    self.vchShortDesc = [[NSString alloc] initWithString:[dic objectForKey:@"vchShortDesc"]]; 

    self.iVehicleID = [[NSString alloc] initWithString:[dic objectForKey:@"iVehicleID"]]; 

    self.iProductClassID = [[NSString alloc] initWithString:[dic objectForKey:@"iProductClassID"]]; 

    self.dtDateMod = [[NSString alloc] initWithString:[dic objectForKey:@"dtDateMod"]]; 

    self.txtBullet1 = [[NSString alloc] initWithString:[dic objectForKey:@"txtBullet1"]]; 

    self.txtBullet2 = [[NSString alloc] initWithString:[dic objectForKey:@"txtBullet2"]]; 

    self.txtBullet3 = [[NSString alloc] initWithString:[dic objectForKey:@"txtBullet3"]]; 

    self.txtBullet4 = [[NSString alloc] initWithString:[dic objectForKey:@"txtBullet4"]]; 

    self.txtBullet5 = [[NSString alloc] initWithString:[dic objectForKey:@"txtBullet5"]]; 

    self.iUniqueIdentifier = [[NSString alloc] initWithString:[dic objectForKey:@"iUniqueIdentifier"]]; 

    self.dtDateLastTouched = [[NSString alloc] initWithString:[dic objectForKey:@"dtDateLastTouched"]]; 

    self.txtNote6 = [[NSString alloc] initWithString:[dic objectForKey:@"txtNote6"]]; 

    self.InstallTime = [[NSString alloc] initWithString:[dic objectForKey:@"InstallTime"]]; 

    self.SGID = [[NSString alloc] initWithString:[dic objectForKey:@"SGID"]]; 

    self.CURTID = [[NSString alloc] initWithString:[dic objectForKey:@"CURTID"]]; 

    self.SGRetail = [[NSString alloc] initWithString:[dic objectForKey:@"SGRetail"]]; 

    self.SGMemPrice = [[NSString alloc] initWithString:[dic objectForKey:@"SGMemPrice"]]; 

    self.InstallSheet = [[NSString alloc] initWithString:[dic objectForKey:@"InstallSheet"]]; 

    self.mHitchJobber = [[NSString alloc] initWithString:[dic objectForKey:@"mHitchJobber"]]; 

    self.CatID = [[NSString alloc] initWithString:[dic objectForKey:@"CatID"]]; 

    self.ParentID = [[NSString alloc] initWithString:[dic objectForKey:@"ParentID"]]; 

    return self; 
} 

-(NSString *) description 
{ 
    return [NSString stringWithFormat:@"iProductID = %@\n vchProductCode = %@\n vchPriceCode = %@\n vchHitchUPC = %@\n mHitchList = %@\n mHitchMap = %@\n fShippingWeight = %@\n vchWC = %@\n vchCapacity = %@\n txtNote1 = %@\n txtNote2 = %@\n txtNote3 = %@\n txtNote4 = %@\n vchDrilling = %@\n vchUPCList = %@\n vchExposed = %@\n vchShortDesc = %@\n iVehicleID = %@\n iProductClassID = %@\n dtDateMod = %@\n txtBullet1 = %@\n txtBullet2 = %@\n txtBullet3 = %@\n txtBullet4 = %@\n txtBullet4 = %@\n txtBullet5 = %@\n iUniqueIdentifier = %@\n dtDateLastTouched = %@\n txtNote6 = %@\n InstallTime = %@\n SGID = %@\n CURTID = %@\n SGRetail = %@\n SGMemPrice = %@\n InstallSheet = %@\n mHitchJobber = %@\n CatID = %@\n ParentID = %@\n", iProductID, vchProductCode, vchPriceCode, vchHitchUPC, mHitchList, mHitchMap, fShippingWeight, vchWC, vchCapacity, txtNote1, txtNote2, txtNote3, txtNote4, vchDrilling, vchUPCList, vchExposed, vchShortDesc, iVehicleID, iProductClassID, dtDateMod, txtBullet1, txtBullet2, txtBullet3, txtBullet4,txtBullet5, iUniqueIdentifier, dtDateLastTouched,txtNote6,InstallTime,SGID,CURTID,SGRetail,SGMemPrice,InstallSheet,mHitchJobber,CatID, ParentID]; 
} 

@end 

忽略了一個事實,它很長我也試着剛纔設置的屬性,但隨後我的產品沒有必須的任何值。所以我alloc'd所有屬性,不知道這是 「正確的」

產品的使用 picker.h

#import <UIKit/UIKit.h> 

@class Vehicle; 
@class Product; 



@interface Picker : UITableViewController <NSXMLParserDelegate> { 
    NSString *currentRow; 
    NSString *currentElement; 
    Vehicle *vehicle; 
} 

@property (nonatomic, retain) NSMutableArray *dataArray; 

//@property (readwrite, copy) NSString *currentRow; 
//@property (readwrite, copy) NSString *currentElement; 

-(void) getYears:(NSString *)string; 
-(void) getMakes:(NSString *)year; 
-(void) getModels:(NSString *)year: (NSString *)make; 
-(void) getStyles:(NSString *)year: (NSString *)make: (NSString *)model; 

-(void) getHitch:(NSString *)year: (NSString *)make: (NSString *)model: (NSString *)style; 

-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName; 

-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string; 

-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict; 

@end 

實現的.m的

#import "Product.h" 
#import "Picker.h" 
#import "KioskAppDelegate.h" 
#import "JSON.h" 
#import "Vehicle.h" 

@implementation Picker 

@synthesize dataArray; 
-(void) getHitch:(NSString *)year: (NSString *)make: (NSString *)model: (NSString *)style{ 
    currentRow = [NSString stringWithString:@"z:row"]; 
    currentElement = [NSString stringWithString:@"gethitch"]; 

    //Reinitialize data array 
    [self.dataArray removeAllObjects]; 
    [self.dataArray release]; 
    self.dataArray = [[NSArray alloc] initWithObjects:nil]; 

    //Build url & string 
    NSString *thisString = [[NSString alloc] initWithString:@""]; 
    thisString = [NSString stringWithFormat:@"http://api.curthitch.biz/AJAX_CURT.aspx?action=GetHitch&dataType=json&year=%@&make=%@&model=%@&style=%@",year,make,model,style]; 

    //Request 
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:thisString]]; 

    //Perform request and fill data with json 
    NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 

    //Get string from data 
    NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]; 

    //set up parser 
    SBJsonParser *parser = [[SBJsonParser alloc] init]; 

    //parse json into object 
    NSArray *tempArray = [parser objectWithString:json_string error:nil]; 
    for (NSDictionary *dic in tempArray) { 
     Product *tempProduct = [[Product alloc] initWithDict:dic]; 
     NSLog(@"is tempProduct valid %@", (tempProduct) ? @"YES" : @"NO"); 
     [self.dataArray addObject:tempProduct]; 
    } 
} 

@end 

所以我剝離出來所有的表格方法和misc垃圾無關緊要。最後,我的問題是將「tempProduct」對象添加到可變數組dataArray中,以便我可以自定義表格單元格。 使用json框架im解析出一些返回一個NSDictionary對象數組的json。通過我的字典對象看起來不錯,我用我的所有字段的屬性填充我的自定義對象,這些字段都很好,並且值看起來正確。然而,我不能將此添加到數組中,我試過幾個不同的實現不起作用。不知道我做錯了什麼。在某些情況下,執行po tempProduct會打印說明,有時不會。與右鍵單擊變量並選擇打印說明相同。

實際的錯誤信息

2011-02-22 15:53:56.058 Kiosk[8547:207] -[__NSArrayI addObject:]: unrecognized selector sent to instance 0x4e1ba40 
2011-02-22 15:53:56.060 Kiosk[8547:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI addObject:]: unrecognized selector sent to instance 0x4e1ba40' 
*** Call stack at first throw: 
(
    0 CoreFoundation      0x00dbabe9 __exceptionPreprocess + 185 
    1 libobjc.A.dylib      0x00f0f5c2 objc_exception_throw + 47 
    2 CoreFoundation      0x00dbc6fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187 
    3 CoreFoundation      0x00d2c366 ___forwarding___ + 966 
    4 CoreFoundation      0x00d2bf22 _CF_forwarding_prep_0 + 50 
    5 Kiosk        0x00003ead -[Picker getHitch::::] + 1091 
    6 Kiosk        0x00003007 -[Picker tableView:didSelectRowAtIndexPath:] + 1407 
    7 UIKit        0x0009b794 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140 
    8 UIKit        0x00091d50 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 219 
    9 Foundation       0x007937f6 __NSFireDelayedPerform + 441 
    10 CoreFoundation      0x00d9bfe3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19 
    11 CoreFoundation      0x00d9d594 __CFRunLoopDoTimer + 1220 
    12 CoreFoundation      0x00cf9cc9 __CFRunLoopRun + 1817 
    13 CoreFoundation      0x00cf9240 CFRunLoopRunSpecific + 208 
    14 CoreFoundation      0x00cf9161 CFRunLoopRunInMode + 97 
    15 GraphicsServices     0x0102e268 GSEventRunModal + 217 
    16 GraphicsServices     0x0102e32d GSEventRun + 115 
    17 UIKit        0x0003442e UIApplicationMain + 1160 
    18 Kiosk        0x0000239a main + 104 
    19 Kiosk        0x00002329 start + 53 
) 
terminate called after throwing an instance of 'NSException' 

回答

6

你的問題是這樣的:

self.dataArray = [[NSArray alloc] initWithObjects:nil]; 

有幾件事錯在這裏:

  1. 這是內存泄漏。該屬性被聲明爲retain屬性,並且您正在給它一個擁有對象。因此,您已聲明對象兩次的所有權爲(一次使用+alloc,然後再使用retaining它在屬性設置器方法中),但您只會放棄一次所有權(當對象被釋放時)。你不給self一個可變數組。你給它一個不變的數組。換句話說,NSArray != NSMutableArray。創建NSArray後,您無法更改其內容。你只能用NSMutableArray來做到這一點。

爲了解決這個問題,你應該行更改爲:

self.dataArray = [NSMutableArray array]; 

除此之外,你有內存泄漏所有的地方。

  • 例如,您的-[Product initWithDict:]方法中幾乎每一行都是內存泄漏。

    self.propertyName = [dic objectForKey:@"dictionary key"]; 
    
  • 這是完全錯誤:

    [self.dataArray release]; 
    

    你應該這樣做:

    self.dataArray = nil; 
    
  • 這是另一種泄漏:

    NSString *thisString = [[NSString alloc] initWithString:@""]; 
    thisString = [NSString stringWithFormat:@"http://api.curthitch.biz/AJAX_CURT.aspx?action=GetHitch&dataType=json&year=%@&make=%@&model=%@&style=%@",year,make,model,style]; 
    
    他們都應該被替換

    你s HOULD做:

    NSString *thisString = [NSString stringWithFormat:@"http://api.curthitch.biz/AJAX_CURT.aspx?action=GetHitch&dataType=json&year=%@&make=%@&model=%@&style=%@",year,make,model,style]; 
    
  • +alloc通過json_string引用的字符串,但你永遠不release它。

  • you +alloc an SBJsonParser,但你從來沒有release它。
  • you +alloc a Product在您的for循環的每次迭代中,但您從來沒有release它。

很明顯,你還沒有讀過一些基本的文檔。我強烈建議你做:

+0

或者 - 不要在初始化程序中調用self。即'dataArray = [[NSMutabelArray alloc] init];'。但請記住要在'dealloc'中發佈它, – Abizern 2011-02-22 23:13:06

+0

@Abizern是的,這是很好的建議。我的回答雖然在技術上不是最佳實踐,但是打算用他的代碼改變最少量的東西。 (這對他來說可能更容易理解) – 2011-02-22 23:14:16

+1

NP。但是他將會看到許多用這種方式編寫的示例代碼,所以提到它是有道理的。 – Abizern 2011-02-22 23:16:01

0

你的問題是,你分配一個NSArray而不是NSMutableArray賦值給self.dataArray。嘗試[[NSMutableArray alloc] init] 另外,如果你分配/ init對象,然後使用保留,你將過度保留你的對象。在分配時自動釋放它們

相關問題