【发布时间】:2011-06-11 14:32:54
【问题描述】:
我已经编写了这个与文本字段相关联的简单操作方法。
每次我在文本字段中输入文本时,都会执行 PDF 中的搜索,PDFView 会自动滚动到选择:
- (IBAction) search:(id)id
{
NSString *query = [self.searchView stringValue]; // get from textfield
selection = [document findString: query fromSelection:NULL withOptions:NSCaseInsensitiveSearch];
if (selection != nil)
{
[self.pdfView setCurrentSelection:selection];
[self.pdfView scrollSelectionToVisible:self.searchView];
}
}
问题是经过 3 或 4 次搜索后,我在第 (i) 行得到 EXC_BAD_ACCESS。
如果我调试,我会看到该查询包含 NSCFString 而不是 NSString。
我认为这是一个内存管理问题..但是在哪里?
我在一个简单的测试用例中复制了同样的问题:
@interface PDFRef_protoTests : SenTestCase {
@private
PDFDocument *document;
}
........
- (void)setUp
{
[super setUp];
document = [[PDFDocument alloc] initWithURL: @"a local url ..."];
}
- (void)test_exc_bad_access_in_pdfdocument
{
for (int i =0 ;i<100; i++)
{
NSString *temp;
if (i % 2 == 0) temp = @"home";
else if (i % 3 ==0) temp = @"cocoa";
else temp=@"apple";
PDFSelection *selection = [document findString: temp
fromSelection:nil
withOptions:NSCaseInsensitiveSearch];
NSLog(@"Find=%@, iteration=%d", selection, i);
}
}
更新:
1) 如果我每次执行第二次搜索时都使用异步搜索(方法 beginFindString: withOptions),似乎也会发生这种情况。
2) 我在 MacRuby 问题跟踪中发现了一个与我类似的问题:http://www.macruby.org/trac/ticket/1029
3) 似乎如果我暂时禁用垃圾收集,它会起作用,但内存会增加。 我写了类似的东西:
[[NSGarbageCollector defaultCollector] disable];
[[NSGarbageCollector defaultCollector] enable];
周边搜索代码
另一个更新
非常奇怪的是,有时一切正常。比我清理和重建,问题再次出现。从某种角度来看,并不是 100% 可重现的。我怀疑 PDFKit 中的错误或我必须做的一些编译器设置
再次更新
亲爱的,这似乎很疯狂。我会专注于测试用例,它非常简单并且很容易复制问题。它出什么问题了?此测试用例仅在我禁用(通过代码或通过项目设置)GC 时才有效
另一个更新
男孩,这似乎是一个错误,但我从 Apple 网站 (http://developer.apple.com/library/mac/#samplecode/PDFKitLinker2/Introduction/Intro.html#//apple_ref/doc/uid/DTS10003594) 下载了一个名为 PDFLinker 的示例。这个例子实现了一个 PDFViewer。我的应用程序的代码和这个例子非常相似。对于同一个 PDF 的相同搜索操作,我的内存增加到 300/400 MB,而 PDFLinker 增加到 190MB。显然我的代码有问题。但我正在一点一点地比较它,我认为我没有插入内存泄漏(而且 Instrument 没有给我任何证据)。也许有一些项目范围的设置?
尚未更新 从 64 位更改为 32 位内存消耗降低。 64位和PDFKit肯定有问题。 BTW 在第二次搜索时仍然是 EXC_BAD_ACCESS
解决方案 关键点是带有垃圾收集的 PDFKit 被窃听。 如果我禁用 GC 一切正常。 我遇到了另一个使我的分析变得复杂的问题:我在项目设置上禁用了 GC,但在目标设置上仍然启用了 GC。因此,Apple 的示例 PDFLinked2 有效,而我的无效。
【问题讨论】:
-
如果我删除垃圾收集器,它似乎可以工作(但可能有内存泄漏)
-
附注,
NSCFString是NSStrings 在内部存储的方式,以允许在 Foundation 和 CoreFoundation 对象之间进行桥接。所以这不是问题或问题。 -
文档是如何声明/分配的?
-
document是一个在构造函数中初始化的实例变量
-
您的解决方案看起来与我回答的编辑部分非常相似。然而,我的回答遭到了反对,但从您的解决方案来看,它应该是公认的答案。
标签: objective-c cocoa macruby pdfkit