I have a weird problems with NSArray
where some of the members of the objects in my array are going out of scope but not the others:
I have a simple object called Section. It has 3 members.
@interface Section : NSObject {
NSNumber *section_Id;
NSNumber *routeId;开发者_如何转开发
NSString *startLocationName;
}
@property(nonatomic,retain) NSNumber *section_Id;
@property(nonatomic,retain) NSNumber *routeId;
@property(nonatomic,retain) NSString *startLocationName;
@end
@implementation Section
@synthesize section_Id;
@synthesize routeId;
@synthesize startLocationName;
//Some static finder methods to get list of Sections from the db
+ (NSMutableArray *) findAllSections:{
- (void)dealloc {
[section_Id release];
[routeId release];
[startLocationName release];
[super dealloc];
}
@end
I fill it from a database in a method called findAllSection
self.sections = [Section findAllSections];
In find all sections I create some local variables fill them with data from db.
NSNumber *secId = [NSNumber numberWithInt:id_section];
NSNumber *rteId = [NSNumber numberWithInt:id_route];
NSString *startName = @"";
Then create a new Section and store these local variable's data in the Section
Section *section = [[Section alloc] init];
section.section_Id = secId;
section.routeId = rteId;
section.startLocationName = startName;
Then I add the section to the array
[sectionsArray addObject:section];
Then I clean up, releasing local variables and the section I added to the array [secId release]; [rteId release]; [startName release]; [locEnd_name release];
[section release];
In a loop repeat for all Sections (release local variables and section is done in every loop)
The method returns and I check the array and all the Sections are there. I cant seem to dig further down to see the values of the Section objects in the array (is this possible)
Later I try and retrieve one of the Sections
I get it from the array
Section * section = [self.sections objectAtIndex:row];
Then check the value
NSLog(@" SECTION SELECTED:%@",section.section_Id);
But the call to section.section_Id
crashed as section.section_Id
is out of scope.
I check the other members of this Section object and they're ok. After some trial and error I find that by commenting out the release of the member variable the object is OK.
//[secId release];
[rteId release];
[startName release];
[locEnd_name release];
[section release];
My questions are:
Am I cleaning up okay?
Should I release the object added to an array and the local variable in the function?
Is my dealloc okay in Section?
Does this code look ok and should I be looking elsewhere for the problem?
I'm not doing anything complicated just filling array from DB use it in Table Cell.
I can comment out the release but would prefer to know why this works, and if I shouldn't be doing this. The only place that secId
is released is in the dealloc.
You should not be releasing secId
, rteId
, or startName
. secId
and rteId
are pointers to NSNumber
instances created with a factory method that returns an already-autoreleased object. Static strings (i.e. @""
) do not need to be released. You need to re-read the Memory Management Programming Guide. Then read it again ;-) It will be your friend.
You're releasing objects you don't own. You should read the memory management rules.
I'll second (third) the suggestion to read the memory management rules.
The TL;DR version is anything you alloc
and call a method with init
in the method name on is your responsibility to release. For instance:
NSString *string = [[NSString alloc] initWithFormat:@"%@", someObject];
In this case you must release string
. However:
NSString *string = [NSString stringWithFormat:@"%@", someObject];
Here string
is autoreleased. It's basically equivalent to this:
NSString *string = [[[NSString alloc] initWithFormat@"%@", someObject] autorelease];
...meaning that the next time through the event loop (which means possibly as soon as your function returns), the system will send a release
message to it for you. Apple calls these "convenience methods".
If you have something like this:
NSString *string = @"foo";
Then string
is pointing to an instance of NSString that is created by the runtime when your program initializes and won't go out of scope until your program terminates. Never release
these either.
Again, read the guidelines and bookmark them. But this should answer your direct question.
精彩评论