gpt4 book ai didi

objective-c - 示例 Cocoa 应用程序,引用计数,[池耗尽] 产生 EXC_BAD_ACCESS?

转载 作者:行者123 更新时间:2023-12-03 16:26:40 25 4
gpt4 key购买 nike

我正在处理Cocoa Programming for Mac OS X (3rd ed)在第 4 章中我编写了这个应用程序:

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

//create the date object
NSCalendarDate *now = [[NSCalendarDate alloc] init];

//seed random # generator
srandom(time(NULL));

NSMutableArray *array;
array = [[NSMutableArray alloc] init];
int i;
for (i=0; i<10; i++){
//create a date/time that is 'i' weeks from now
NSCalendarDate *iWeeksFromNow;
iWeeksFromNow = [now dateByAddingYears:0
months:0
days:(i*7)
hours:0
minutes:0
seconds:0];

//create a new instance of lottery entry
LotteryEntry *entry = [[LotteryEntry alloc] init];
[entry setEntryDate:iWeeksFromNow];

[array addObject:entry];
[entry release];
}
[now release];
now = nil;

for (LotteryEntry *entryToPrint in array) {
NSLog(@"%@", entryToPrint);
}
[array release];
array = nil;

NSLog(@"about to drain the pool... (%@)", pool);
[pool drain];
NSLog(@"done");
NSLog(@"GC = %@", [NSGarbageCollector defaultCollector]);
return 0;
}

LotteryEntry 类如下所示:

@implementation LotteryEntry

- (void)setEntryDate:(NSCalendarDate *)date
{
entryDate = date;
}

- (NSCalendarDate *)entryDate
{
return entryDate;
}

- (int)firstNumber
{
return firstNumber;
}

- (int)secondNumber
{
return secondNumber;
}

- (id)init
{
return [self initWithDate:[NSCalendarDate calendarDate]];
}

- (id)initWithDate:(NSCalendarDate *)date
{
if(![super init])
return nil;

NSAssert(date != nil, @"Argument must be non-nil");

firstNumber = random() % 100 + 1;
secondNumber = random() % 100 + 1;
entryDate = [date retain];
return self;
}

- (NSString *)description
{
NSString *result;
result = [[NSString alloc] initWithFormat:@"%@ = %d and %d",
[entryDate descriptionWithCalendarFormat:@"%b %d %Y"],
firstNumber,
secondNumber];
return result;
}

- (void)dealloc
{
NSLog(@"deallocating %@", self);
[entryDate release];
[super dealloc];
}

@end

如您所见,我在这里保留和释放对象。我很确定我的代码与书中的代码匹配,但是当我运行该应用程序时,在 [池排水] 处我收到此消息:

Program received signal: “EXC_BAD_ACCESS”.

我不确定是什么原因造成的。我希望我错过了一些愚蠢的事情,但我肯定会感谢其他几双眼睛的关注。提前致谢!

(旁注:我是一名 .NET 开发人员,因此引用计数对我来说非常陌生!)

最佳答案

这个方法似乎也有一个错误:

- (id)initWithDate:(NSCalendarDate *)date
{
if(![super init])
return nil;

NSAssert(date != nil, @"Argument must be non-nil");

firstNumber = random() % 100 + 1;
secondNumber = random() % 100 + 1;
entryDate = [date retain];
return self;
}

您实际上是在丢弃 [super init] 的结果,虽然在这种情况下这可能不是问题,但在其他情况下可能会导致严重的问题。您应该“始终”像这样构建 init 方法:

- (id)initWithDate:(NSCalendarDate *)date
{
if(self = [super init]) {
NSAssert(date != nil, @"Argument must be non-nil");

firstNumber = random() % 100 + 1;
secondNumber = random() % 100 + 1;
entryDate = [date retain];
}
return self;

如果你不打算从 init 方法返回 self(例如它是一个工厂或类似的奇怪的东西),你应该记住释放 self。已经分配了,如果不归还,就无法正常释放。示例:

- (id) init
{
NSObject* newSelf = [[NSObject alloc] init];

[self release];
return newSelf;
}

关于objective-c - 示例 Cocoa 应用程序,引用计数,[池耗尽] 产生 EXC_BAD_ACCESS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/473397/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com