views:

117

answers:

3

Hello everyone

I hope to add objects to a NSMutableArray "myArray", The NSMutableArray is the array for FileObj which has a NSString property "fileName"

#import <UIKit/UIKit.h>


@interface FileObj :  NSObject  {

    NSString *fileName;


}


-(void) setfileName:(NSString *)s ;
-(NSString *) getfileName ;


@end

//
//  File.m//

#import "File.h"


@implementation FileObj
 -(void) setfileName:(NSString *)s ;
{
    fileName=s;
}
-(NSString *) getfileName ;
{
    return fileName;
}
@end

I initialize the myArray here:

NSMutableArray *temarray;
temarray=[[NSMutableArray alloc] init];
self.myArray=temarray;
[temarray release];

the codes to add object to myArray

FileObj *newobj=[[FileObj alloc]init ];
NSString  *fieldValue2 = [[NSString alloc]   initWithUTF8String:@"aaaa"];
[newobj setfileName:fieldValue2];



[myArray addObject:newobj];

[fieldValue2 release]; //**if I enabled the line, it will cause crash**
                       //**if I disable the line, it will cause memory leak**


[newobj release];

Welcome any comment

Thanks

interdev

A: 

The crash occurs because the NSString instance is not retained anymore.

A common pattern is to retain NSString properties, either declaratively with @property or by hand.

You should modify the setter like this:

-(void) setfileName:(NSString *)s ;
{
    [s retain]; // <- Retain new value
    [filename release]; // <- Release old value
    fileName=s;
}
Laurent Etiemble
+1  A: 

First you should look into ObjC naming conventions. There is no -get methods in ObjC. It's also a good idea to prefix your classes with your own 2 letters (like NS).

Your setter value assignment is invalid and the NSString initialization unnecessary. I would strongly recommend introductory material to you!

@interface MYFileObject : NSObject {

    NSString *_fileName;
}

- (void)setFileName:(NSString *)theString;
- (NSString *)fileName;

@end

and the implementation

@implementation MYFileObject

- (void)setFileName:(NSString *)theString {
    [_fileName release];
    _fileName = [theString copy];
}

- (NSString *)fileName {
    return [[_fileName copy] autorelease];
}

- (void)dealloc {
    [_fileName release];
    [super dealloc];
}

@end

You would add an object like this...

NSMutableArray *myAry = [[NSMutableArray alloc] init];
MYFileObject *obj = [[MYFileObject alloc] init];
[obj setFileName:@"thefilename.txt"];

[myAry addObject:obj];
[obj release];

I would recommend using properties instead of defining your own getters/setters. You could also use the NSMutableArrays' designated initializers for fast array creation.

Look here for how to use properties: http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html

Erik Aigner
+1  A: 

Why bother with getters and setters? Use declared property already!

@interface FileObj :  NSObject  {
    NSString *fileName;
}
@property(retain,nonatomic) NSString* fileName;  // <---
@end

...

@implementation FileObj
@synthesize fileName;    /// <---
-(void)dealloc {
  [fileName release];    // Remember to release the object on dealloc.
  [super dealloc];
}
@end

...

FileObj *newobj=[[FileObj alloc] init];
NSString  *fieldValue2 = [[NSString alloc] initWithUTF8String:@"aaaa"];

newobj.fileName = fieldValue2;   /// <----

[myArray addObject:newobj];

[fieldValue2 release];
[newobj release];
KennyTM
This also works for me. But I selected eaigner's as Answer because I do not need to change more source codes. Thanks a lot.