我对NSArray
有一些奇怪的问题,我的数组中某些对象的成员超出了范围而不是其他成员:
我有一个名为Section的简单对象。 它有3名成员。
@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
我在一个名为findAllSection
self.sections = [Section findAllSections];
在查找所有部分时,我创建了一些局部变量,用db。中的数据填充它们。
NSNumber *secId = [NSNumber numberWithInt:id_section];
NSNumber *rteId = [NSNumber numberWithInt:id_route];
NSString *startName = @"";
然后创建一个新的Section并将这些局部变量的数据存储在Section
中Section *section = [[Section alloc] init];
section.section_Id = secId;
section.routeId = rteId;
section.startLocationName = startName;
然后我将该部分添加到数组
[sectionsArray addObject:section];
然后我清理,释放局部变量和我添加到数组的部分 [secId release]; [rteId发布]; [startName release]; [locEnd_name release];
[section release];
在循环重复所有章节(释放局部变量,并在每个循环中完成部分)
该方法返回并检查数组,所有部分都在那里。我似乎无法深入挖掘数组中的Section对象的值(这是可能的)
稍后我尝试检索其中一个部分
我是从数组中得到的
Section * section = [self.sections objectAtIndex:row];
然后检查值
NSLog(@" SECTION SELECTED:%@",section.section_Id);
但是对section.section_Id
的调用因section.section_Id
而崩溃超出了范围。
我检查了这个Section对象的其他成员,他们没问题。 经过一些试验和错误后,我发现通过注释掉成员变量的释放,对象就可以了。
//[secId release];
[rteId release];
[startName release];
[locEnd_name release];
[section release];
我的问题是:
我清理好吗?
我应该释放添加到数组的对象和函数中的局部变量吗?
我的dealloc是否在分区?
这段代码看起来不错吗?我应该在别处寻找问题吗?
我没有做任何复杂的事情,只需从DB填充数组就可以在Table Cell中使用它。
我可以评论该版本,但我更愿意知道为什么这样做,如果我不应该这样做。 secId
被释放的唯一地方是dealloc。
答案 0 :(得分:4)
您不应该发布secId
,rteId
或startName
。 secId
和rteId
是使用返回已经自动释放的对象的工厂方法创建的NSNumber
实例的指针。不需要释放静态字符串(即@""
)。您需要重新阅读Memory Management Programming Guide。然后再读一遍;-)这将是你的朋友。
答案 1 :(得分:3)
您正在发布您不拥有的对象。您应该阅读memory management rules。
答案 2 :(得分:2)
我将第二个(第三个)建议阅读内存管理规则。
TL; DR版本是您alloc
的任何内容,并且在方法名称中使用init
调用方法是您有责任发布的。例如:
NSString *string = [[NSString alloc] initWithFormat:@"%@", someObject];
在这种情况下,您必须释放string
。但是:
NSString *string = [NSString stringWithFormat:@"%@", someObject];
此处string
已自动释放。它基本上等同于:
NSString *string = [[[NSString alloc] initWithFormat@"%@", someObject] autorelease];
...意味着下一次通过事件循环(这意味着可能一旦函数返回),系统将为您发送release
消息。 Apple将这些称为“便利方法”。
如果你有这样的事情:
NSString *string = @"foo";
然后string
指向NSString的一个实例,该实例是在程序初始化时由运行时创建的,并且在程序终止之前不会超出范围。从来没有release
这些。
再次阅读指南并将其加入书签。但这应该回答你的直接问题。