Objective c 是什么导致SIGSEGV使用块?
我有以下代码。我偶尔会得到一个SIGSEGV。我觉得我缺少了一些关于使用块进行内存管理的东西。通过自动释放到此块的replacedUrls安全吗?修改实例变量formattedText怎么样Objective c 是什么导致SIGSEGV使用块?,objective-c,objective-c-blocks,Objective C,Objective C Blocks,我有以下代码。我偶尔会得到一个SIGSEGV。我觉得我缺少了一些关于使用块进行内存管理的东西。通过自动释放到此块的replacedUrls安全吗?修改实例变量formattedText怎么样 NSMutableSet* replacedUrls = [[[NSMutableSet alloc] init] autorelease]; NSError *error = nil; NSDataDetector *detector = [NSDataDetector dat
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
}
}];
NSMutableSet*replacedUrls=[[NSMutableSet alloc]init]autorelease];
n错误*错误=nil;
NSDataDetector*detector=[NSDataDetector DataDetectorWithType:
(NSTextCheckingTypeLink | NSTextCheckingTypePhoneNumber)
错误:&错误];
如果(错误){
返回;
}
[检测器枚举匹配安装:self.formattedText
选项:0
范围:NSMakeRange(0,[self.formattedText长度])
usingBlock:^(NSTextCheckingResult*结果,NSMatchingFlags标志,布尔*停止){
@试一试{
if(result.resultType==NSTextCheckingTypePhoneNumber){
如果(!result.phoneNumber){
//不确定这是否可行
返回;
}
self.formattedText=[self.formattedText stringByReplacingOccurrencesOfString:result.phoneNumber
withString:[NSString stringWithFormat:@',result.phoneNumber,result.phoneNumber]];
}
else if(result.resultType==NSTextCheckingTypeLink){
如果(!result.URL){
//不确定这是否可行
返回;
}
NSString*fullUrl=[result.URL绝对字符串];
如果(!fullUrl){
返回;
}
if([replacedUrls containsObject:fullUrl]){
返回;
}
//不确定这是否可行
if([result.URL主机]&&&[result.URL路径]){
NSString*urlWithNoScheme=[NSString stringWithFormat:@“%@%@”,[result.URL主机],[result.URL路径]];
//全部替换http://www.google.com 访问www.google.com
self.formattedText=[self.formattedText stringByReplacingOccurrencesOfString:fullUrl
带字符串:urlWithNoScheme];
//将所有www.google.com替换为http://www.google.com
NSString*replaceText=[NSString stringWithFormat:@',fullUrl,fullUrl];
self.formattedText=[self.formattedText stringByReplacingOccurrencesOfString:urlWithNoScheme
带字符串:replaceText];
[replacedUrls addObject:fullUrl];
}
}
}
@捕获(NSException*忽略){
//忽略任何问题
}
}];
您遇到的问题似乎与内存管理有关。首先搜索字符串self.formattedText
。这意味着,在进行此搜索时,您的NSDataDetector
实例可能需要访问字符串以读取字符等。只要self.formattedText
没有被释放,这一切都很好。通常,即使对于这样的块方法,调用方也有责任保留参数,直到函数调用结束
当您在match found块内更改self.formattedText
的值时,旧值将自动释放(假设这是retain
属性)。我不知道NSDataDetector可能会进行缓存,也不知道与自动释放池相关的问题,但我非常确定这可能会导致问题
我的建议是将
[NSString-stringWithString:self.formattedText]
作为枚举匹配安装:
参数传递,而不是普通的self.formattedText
。通过这种方式,您可以向NSDataDetector传递一个实例,该实例在自动释放池耗尽之前不会被释放。经过一些阅读,我肯定看到了我将在何处创建一个保留周期,因为self将被保留。不过,我仍然不确定这将如何产生实际问题。最不可靠的一行是“if(error){return;}”,但我也不确定这是如何导致问题的(如果此时返回,代码将正常恢复,对吗?)。保持自我不一定会导致保持循环,保持循环也不会导致SIGSEGV;是的,那句台词很奇怪。我甚至不确定这是否必要。我想我是把它作为一种精神检查加上去的。在我们加入那条线之前,它得到了一个SIGSEGV。大多数if语句都是添加的,因为崩溃报告只是指向一般块,而不是特定行。追查这个问题有点烦人。在这里修改格式化文本安全吗?对于您关于优雅返回的问题,它确实返回得很好。我们所做的就是用正确转义的URL替换URL,以便它们正确地显示在控件中。可能会有更好的实施;奇怪的是,虽然我收到了报告,但我不能为自己的生活重新创造。要么是那个,要么就是这个。不管怎样,谢谢你的帮助。非常感谢。我还没有完全测试过这一点,但我认为你的答案是值得的。:)