非常に単純な Xcode プロジェクトを取得しました。次のコンテンツを持つ単一のファイル アプリ デリゲートがあります。
@interface TestController : NSObject <NSApplicationDelegate, NSMetadataQueryDelegate>
@property (assign) IBOutlet NSWindow *window;
@property (strong, nonatomic) NSString *text;
@property (strong, nonatomic) NSMetadataQuery *query;
@end
@implementation TestController
@synthesize window = _window;
@synthesize text = _text;
@synthesize query = _query;
- (id)init {
self = [super init];
if (self) {
self.query = [[NSMetadataQuery alloc] init];
self.query.searchScopes = [NSArray arrayWithObject:NSMetadataQueryLocalComputerScope];
self.query.predicate = [NSPredicate predicateWithFormat:@"kMDItemTextContent LIKE[cd] %@", @"test"];
self.query.delegate = self;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(queryNote:)
name:nil
object:self.query];
[self.query startQuery];
[self addObserver:self forKeyPath:@"text" options:0 context:NULL];
}
return self;
}
- (void)queryNote:(NSNotification *)note {
NSLog(@"queryNote: %@", [note name]);
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"text"]) {
NSString *str = self.text ? self.text : @"test";
self.query.predicate = [NSPredicate predicateWithFormat:@"kMDItemTextContent LIKE[cd] %@", str];
}
}
@end
インターフェイス ビルダーには、コンテンツ配列がテスト コントローラーのquery.results
キーパスにバインドされている単一の配列コントローラーがあります。値が文字列にバインドされている NSSearchField もありtext
ます。検索フィールドに 1 文字入力した瞬間に、プログラム全体がクラッシュしEXC_BAD_ACCESS
ます。これを絞り込んで、self.query.predicate
内部-setText
関数を設定すると、すべてが正常に機能するように見えることがわかりました。self.query.predicate
また、設定を GCD ブロック内にラップすることもできます。問題は、NSMetadataQuery
KVO 通知内から の述語を変更すると、プログラムがクラッシュするのはなぜですか? (すべてがメインスレッドから呼び出されることを確認しました)
テスト プロジェクトを github にアップしているので、簡単にクローンを作成して問題を確認できます。