iPhone内存管理问题

发布于 2024-08-18 23:27:34 字数 969 浏览 9 评论 0原文

我分离了一个调用我的方法的线程,该方法有一个 while 循环。即使我将它们标记为 autoreleasepool,我也会手动释放对象,因为 while 循环可以继续一段时间。

问题是,一段时间后,应用程序因内存问题而崩溃。如果我查看 Instruments,我可以看到分配了一大堆 NSString,并且在图中创建了通往天堂的阶梯。我未能释放什么?

while (keepGettingScores)  
{  
    NSString *jsonString = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];  
    NSDictionary *json = [jsonString JSONValue];  
    [jsonString release];   

    NSMutableArray *scores = [[NSMutableArray alloc] init];  
    [scores setArray:(NSMutableArray*)[[jsonString JSONValue] objectForKey:@"scores"]];

    NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"totalScore" ascending:NO];  
    [scores sortUsingDescriptors:[NSArray arrayWithObject:sorter]];  
    [sorter release];  

    [self performSelectorOnMainThread:@selector(updatePlayerTable:) withObject:scores waitUntilDone:NO];  
    [scores release];  

    [NSThread sleepForTimeInterval:1.0];  
}  

I detach a thread calling my method which has a while-loop. Even though I have them marked as autoreleasepool, I release the objects manually, since the while-loop can continue on for a some time.

The problem is that after a while, the app crashes due to memory problems. If I look in Instruments, I can see a huge pile of NSStrings allocated and a stairway to heaven is created in the graph. What have I failed to release?

while (keepGettingScores)  
{  
    NSString *jsonString = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];  
    NSDictionary *json = [jsonString JSONValue];  
    [jsonString release];   

    NSMutableArray *scores = [[NSMutableArray alloc] init];  
    [scores setArray:(NSMutableArray*)[[jsonString JSONValue] objectForKey:@"scores"]];

    NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"totalScore" ascending:NO];  
    [scores sortUsingDescriptors:[NSArray arrayWithObject:sorter]];  
    [sorter release];  

    [self performSelectorOnMainThread:@selector(updatePlayerTable:) withObject:scores waitUntilDone:NO];  
    [scores release];  

    [NSThread sleepForTimeInterval:1.0];  
}  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

死开点丶别碍眼 2024-08-25 23:27:34

我没有看到任何明显的问题,您的 JSON 库中是否存在问题?

I don't see anything glaring, could there be an issue under the hood in your JSON library?

伤痕我心 2024-08-25 23:27:34

线程执行完毕后,您是否会耗尽池中的资源?

您需要创建一个 NSAutoreleasePool 并在线程执行完毕后调用其排出方法。

在我的一个项目中,我有一个线程需要创建大量自动释放对象,并发现在线程运行时定期耗尽池很有用。

- (void)doStuff:(NSObject *)parent {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];      

    /* Do lots of stuff *.
    /* Periodically, I'd drain and recreate the pool */
    [pool drain];
    pool = [[NSAutoreleasePool alloc] init];
    /* The rest of my stuff */

    [pool drain];
}

并使用 detachNewThreadSelector 调用 doStuff::

Are you draining your pool after your thread is finished executing?

You need to create an NSAutoreleasePool and call its drain method when your thread is finished executing.

In one of my projects, I had a thread that needed to create a lot of autorelease objects and found it useful to periodically drain the pool as the thread was running.

- (void)doStuff:(NSObject *)parent {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];      

    /* Do lots of stuff *.
    /* Periodically, I'd drain and recreate the pool */
    [pool drain];
    pool = [[NSAutoreleasePool alloc] init];
    /* The rest of my stuff */

    [pool drain];
}

And doStuff: is called using detachNewThreadSelector:

倾`听者〃 2024-08-25 23:27:34

好吧,我看到的一些大问题是

1

这个..

[self PerformSelectorOnMainThread:@selector(updatePlayerTable:) withObject:scores waitUntilDone:NO];
传递的分数可能会被其他东西保留,并且也会保留它包含的所有对象。

2

Scores 是一个 nsmutablearray,并且被显式定义为 NOT THREAD SAFE,但您要跨线程传递它。

3

那些[blah JSONvalue]东西应该自动发布,那不是苹果api,苹果没有适用于iphone的公共JSON api。这很可能是 SBJSON 库,它将类别放在苹果类(nsstring、nsarray、nsdictionary 等)上,以方便 JSON 解析。

ok some BIG problems i see is

1

this..

[self performSelectorOnMainThread:@selector(updatePlayerTable:) withObject:scores waitUntilDone:NO];
is passing scores which could be getting retained by something else and that would also retain all the objects it contains.

2

scores is a nsmutablearray and is explicitly defined as NOT THREAD SAFE yet you are passing it across threads.

3

those [blah JSONvalue] things should be autoreleased and that is not apple api, apple has no public JSON api for iphone. that is most likely SBJSON library which puts categories on apple classes(nsstring, nsarray, nsdictionary, etc) for convenient JSON parsing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文