NSString 在时间之前被释放

Posted

技术标签:

【中文标题】NSString 在时间之前被释放【英文标题】:NSString is realeased before time 【发布时间】:2020-05-03 09:15:10 【问题描述】:

我在我的应用程序中使用WKWebView 来通过 javascripthtml 中获取数据,我正在使用以下代码:

NSString *jsCall = [NSString stringWithFormat:@"xxxxxx('%@');",html];

__block NSString *searchJson = nil;

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_sync(dispatch_get_main_queue(), ^
    [self.searchWebView evaluateJavaScript:jsCall completionHandler:^(id result, NSError * _Nullable error) 
        if (error || result == nil || ![result isKindOfClass:[NSString class]]) 
            searchJson = nil;
         else 
            searchJson = result;
        

        dispatch_semaphore_signal(semaphore);
    ];
);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

if ([NSString stringIsNilOrEmpty:searchJson]) 
    return nil;


return [self getResultsWithJSonString:searchJson];

我需要等待响应,所以我使用semaphore_wait 方法,它工作正常,但有时searchJson 会从内存中释放,在[NSString stringIsNilOrEmpty:searchJson] 中我收到此错误:

EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000443439e70

知道如何解决这个已发布的问题吗?我在我的项目中使用非 ARC。

【问题讨论】:

也许在dispatch_sync 的底部尝试dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 或使用dispatch_async 【参考方案1】:

如果是非 ARC,则必须显式保留结果(因为回调可能在不同的线程中),例如

 else 
    searchJson = [result retain];

然后,为避免泄漏,请使用

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[searchJson autorelease]; // << call it here, once !!

if ([NSString stringIsNilOrEmpty:searchJson]) 
    return nil;


return [self getResultsWithJSonString:searchJson];

【讨论】:

我正在使用searchJson 也在另一种方法中,所以当我完成使用它时,我应该调用[searchJson autorelease]? @MTA,你说的 in another 方法是什么意思?规则是保持保留/自动释放对,如图所示;如果你调用第二个自动释放,你会在自动释放池结束时崩溃。如果能显示代码就更好了。

以上是关于NSString 在时间之前被释放的主要内容,如果未能解决你的问题,请参考以下文章

文字 NSString 是自动释放还是需要释放?

自动释放 NSString

NSString 释放问题

NSString - stringWithFormat 自动释放

保留和释放 nsstring

从 NSArray objectAtIndex 返回的 NSString 是自动释放还是保留