gpt4 book ai didi

objective-c - 是什么导致 SIGSEGV 使用 block ?

转载 作者:太空狗 更新时间:2023-10-30 03:33:52 26 4
gpt4 key购买 nike

我有以下代码。我偶尔会收到 SIGSEGV。我有一种感觉,我遗漏了一些关于使用 block 进行内存管理的东西。传递自动释放到此 block 的 replacedUrls 是否安全?修改实例变量 formattedText 怎么样?

    NSMutableSet* replacedUrls = [[[NSMutableSet alloc] init] autorelease];

NSError *error = nil;
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:
(NSTextCheckingTypeLink | NSTextCheckingTypePhoneNumber)
error:&error];
if (error) {
return;
}

[detector enumerateMatchesInString:self.formattedText
options:0
range:NSMakeRange(0, [self.formattedText length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {

@try {
if (result.resultType == NSTextCheckingTypePhoneNumber) {

if (!result.phoneNumber) {
// not sure if this is possible
return;
}

self.formattedText = [self.formattedText stringByReplacingOccurrencesOfString:result.phoneNumber
withString:[NSString stringWithFormat:@"<a href=\"tel://%@\">%@</a>", result.phoneNumber, result.phoneNumber]];
}
else if (result.resultType == NSTextCheckingTypeLink) {

if (!result.URL) {
// not sure if this is possible
return;
}

NSString* fullUrl = [result.URL absoluteString];

if (!fullUrl) {
return;
}

if ([replacedUrls containsObject:fullUrl]) {
return;
}

// not sure if this is possible
if ([result.URL host] && [result.URL path]) {
NSString* urlWithNoScheme = [NSString stringWithFormat:@"%@%@", [result.URL host], [result.URL path]];

// replace all http://www.google.com to www.google.com
self.formattedText = [self.formattedText stringByReplacingOccurrencesOfString:fullUrl
withString:urlWithNoScheme];

// replace all www.google.com with http://www.google.com
NSString* replaceText = [NSString stringWithFormat:@"<a href=\"%@\">%@</a>", fullUrl, fullUrl];
self.formattedText = [self.formattedText stringByReplacingOccurrencesOfString:urlWithNoScheme
withString:replaceText];

[replacedUrls addObject:fullUrl];
}
}
}
@catch (NSException* ignore) {
// ignore any issues
}
}];

最佳答案

您遇到的问题似乎与内存管理有关。您首先搜索字符串 self.formattedText。这意味着,在进行此搜索时,您的 NSDataDetector 实例可能需要访问字符串以读取字符等。这一切都很好,只要 self.formattedText 没有被释放。通常,即使是像这样的 block 方法,调用者也有责任保留参数直到函数调用结束。

当您在找到匹配项的 block 内更改 self.formattedText 的值时,旧值会自动释放(假设这是一个 retain 属性) .我不知道 NSDataDetector 可能会进行缓存,或者与自动释放池等相关的问题,但我很确定这可能会导致问题。

我的建议是你传递 [NSString stringWithString:self.formattedText] 作为 enumerateMatchesInString: 参数,而不是普通的 self.formattedText。这样,您向 NSDataDetector 传递了一个实例,该实例在自动释放池耗尽之前不会被释放。

关于objective-c - 是什么导致 SIGSEGV 使用 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7617861/

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