将自定义对象添加到NSMutableArray

时间:2011-02-22 22:45:07

标签: objective-c json nsmutablearray

开发ios应用。我有一个对象类Product.h和.m以及我的选择器类,它实现我的车辆选择以匹配产品到车辆。文件

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

忽略了它真的很长的事实我也试图设置属性,但后来我的产品没有任何值。所以我为所有属性分配,不确定哪个是“正确的”

产品的使用 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

所以我删除了所有表格方法和错误的垃圾。最后我的问题是将“tempProduct”对象添加到可变数组dataArray中,以便我可以自定义表格单元格。    使用json框架我解析出一些返回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'

2 个答案:

答案 0 :(得分:6)

你的问题是:

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

这里有一些问题:

  1. 这是内存泄漏。该属性被声明为retain属性,并且您将为其提供一个拥有的对象。因此,您已声明对象的所有权(一次使用+alloc,然后再通过retaining声明属性设置器方法),但您只放弃一次所有权(当该对象被解除分配)。
  2. 你没有给self一个可变阵列。你给它一个不可变的数组。换句话说,NSArray != NSMutableArray。创建NSArray后,您无法更改其内容。您只能使用NSMutableArray
  3. 执行此操作

    要解决此问题,您应该将行更改为:

    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];
      

      你应该这样做:

      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

    • +alloc SBJsonParser,但您永远不会release
    • +alloc循环的每次迭代Product for,但您永远不会release

    很明显,您还没有阅读过一些基本文档。我强烈建议您这样做:

答案 1 :(得分:0)

您的问题是您在self.dataArray的作业中分配NSArray而不是NSMutableArray。试试[[NSMutableArray alloc] init] 此外,如果您分配/初始化对象,然后使用保留,您将过度保留您的对象。在转让时自动发布它们