1

コードに何か問題がありますか?この述語を使用して何もフェッチできません。述語をコメントアウトすると、エンティティ「BankDetail」からすべてのオブジェクトをフェッチできます。ですから、問題はこの2行にあると思います。

// self.bankInfo.name is set in prepareForSegue in first view controller
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"info.name = %@",self.bankInfo.name];
[request setPredicate:predicate];

私のモデルには、1対1の関係にある2つのエンティティが含まれています

BankInfo.h

@class BankDetail;

@interface BankInfo : NSManagedObject

@property (nonatomic, retain) NSString * city;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * state;
@property (nonatomic, retain) BankDetail * detail;

@end

BankDetail.h

@class BankInfo;

@interface BankDetail : NSManagedObject

@property (nonatomic, retain) NSString * closeDate;
@property (nonatomic, retain) NSString * updateDate;
@property (nonatomic, retain) NSString * zip;
@property (nonatomic, retain) NSString * acquiringInstitution;
@property (nonatomic, retain) BankInfo * info;

@end

編集:

詳細を提供するには:

  • self.bankInfo.name間違いなく設定されています。述語の行の直前でNSLogします。

  • そして私はこれをviewDidLoad

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"BankDetail" inManagedObjectContext:context];
    NSLog(@"[entity description] is %@",[entity description]);
    

コンソールでこれを取得します。

info = "(<NSRelationshipDescription: 0x6d3eb30>), name info, isOptional 1, isTransient 0, entity BankDetail, renamingIdentifier info, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, destination entity BankInfo, inverseRelationship detail, minCount 1, maxCount 1, isOrdered 0, deleteRule 2";

EDIT2:述語に問題はない ことがわかりました。バグは他の場所での不注意な間違いによって引き起こされます(受け入れられた答えを参照してください、それは名前の変更についてです)。述語について質問がある場合は、この投稿を無視してください。

4

7 に答える 7

1

self.bankInfo.name1対1の関係であり、一致させたい文字列がすでにある場合BankInfoは、その名前のオブジェクトをフェッチして、そのオブジェクトの.detailプロパティにアクセスしてみませんか?それが関係を持つことの要点ですよね?

ただし、述語は機能するはずです。何self.bankInfoですか?self.bankinfo.nameそれが有効な文字列であると確信していますか?

于 2012-09-27T15:52:23.000 に答える
1

述語構造はOKです。基本的な原則を証明するための簡単なプロジェクト については、他の回答を参照してください。

他の回答への応答に基づくと、これNSFetchRequestをaに渡しNSFetchedResultsController、その動作を使用して述語が機能しないと判断しているようです。

私の最初の提案は、述語をログに記録し、それが期待どおりかどうかを確認することです。

NSLog(@"%@", predicate);

それで問題がない場合は、述語が機能していないという理論をテストするためにNSFetchRequest、リクエストを作成した直後に実行し、結果を確認する必要があります。

// self.bankInfo.name is set in prepareForSegue in first view controller
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"info.name = %@",self.bankInfo.name];
[request setPredicate:predicate];

NSArray *results = [myMangedObjectContext executeFetchRequest:request error:nil];

それでも問題が明らかにならない場合は、リクエストから述語を削除し、リクエストを実行し、次のログステートメントを使用して完全な結果を確認することをお勧めします。

NSLog(@"%@", self.bankInfo.name);
NSLog(@"%@", [results valueForKeyPath:@"info.name"]);

最後のlogステートメントは、実際にはすべての銀行名の配列をログに記録するため、inの値self.bankInfo.nameが期待どおりに完全な結果に存在するかどうかを確認できます。

于 2012-09-28T08:14:17.843 に答える
0

最後に、それほどエレガントではない回避策を使用する必要があります。name私も属性を追加することになりBankDetailます。したがって、1つのBankInfo.nameは1つのBankDetail.nameに対応します。次に、述語を使用します。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@",self.bankInfo.name];

BankDetailそしてそれは私が望むことをします:対応するオブジェクトのために1つのオブジェクトをフェッチしBankInfoます。それがベストプラクティスだと思います。

于 2012-09-25T08:52:58.023 に答える
0

私が見る限り、あなたの述語には何の問題もありません。私のアプリには非常によく似たものがあり、正常に動作します。

@class Hospital;

@interface Patient : NSManagedObject
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) Hospital *hospital;

@end

@class Patient;

@interface Hospital : NSManagedObject
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSSet *patients;

@end

私の述語:

request.predicate = [NSPredicate predicateWithFormat:@"hospital.name = %@", self.hospital.name];

したがって、コードに問題はありません。問題は、self.bankInfoまたはself.bankInfo.nameがnullであるかinfoBankDetailオブジェクトに何も含まれていない(関係が設定されていない)ためである必要があります。

于 2012-09-26T23:20:56.630 に答える
0

最初に投稿した述語コードは正しいです。以下は、基本原則をテストするクイックテストプロジェクトです:(「銀行名」を正しくログに記録します)

// Xcode 4.5:
// Create a new iOS Master-Detail project called "BankInfoTest" tick the "Use Core Data" check box (and ARC).
// Delete all files except the AppDelegate and the BankInfoTest data model (leave supporting files).
// Delete all properties and methods from AppDelegate.h
// Paste this code into AppDelegate.m
// Delete the default entity from the data model
// Add "BankInfo" entity, add attribute "name" of type string.
// Add "BankDetail" entity, add relationship called "info" to BankInfo (leave default 1 to 1 type).
// On BankInfo entity add inverse relationship "detail" to BankDetail (leave default 1 to 1 type).
// Select both entities then select "Editor -> Create NSManagedObject Subclass" to create subclasses.
// Run.

#import "AppDelegate.h"
#import "BankDetail.h"
#import "BankInfo.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    /////////////////////////////////////////////////////////////////////////////////////
    // Setup the core data stack.
    /////////////////////////////////////////////////////////////////////////////////////
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"BankInfoTest" withExtension:@"momd"];
    NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

    NSURL *appDocsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    NSURL *storeURL = [appDocsDirectory URLByAppendingPathComponent:@"BankInfoTest"];

    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:nil];

    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    context.persistentStoreCoordinator = coordinator;


    /////////////////////////////////////////////////////////////////////////////////////
    // Load some test data and reset the context.
    /////////////////////////////////////////////////////////////////////////////////////
    BankDetail *detailObject = [NSEntityDescription insertNewObjectForEntityForName:@"BankDetail" inManagedObjectContext:context];
    BankInfo *infoObject = [NSEntityDescription insertNewObjectForEntityForName:@"BankInfo" inManagedObjectContext:context];

    infoObject.name = @"bank name";
    detailObject.info = infoObject;

    [context save:nil];
    [context reset];

    /////////////////////////////////////////////////////////////////////////////////////
    // Test the Predicate
    /////////////////////////////////////////////////////////////////////////////////////
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"BankDetail"];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"info.name = %@", @"bank name"];
    [request setPredicate:predicate];

    NSArray *results = [context executeFetchRequest:request error:nil];
    BankDetail *fetchedObject = [results lastObject];
    NSLog(@"%@", fetchedObject.info.name);

    return YES;
}

@end
于 2012-09-27T09:01:33.890 に答える
0

私はついにバグを修正しました。述語についてではありません。他のファイルの名前を変更するのと同じように、リターンキーを押して変更するだけで、Xcodeエディターの.xcdatamodeldでエンティティの名前をからBankDetailsに変更します。BankDetail

次に、すべての警告が消えるまで、自動生成されたNSManagedObjectサブクラスファイルとそれを参照する他のクラスファイルのさまざまな部分の名前を手動で変更します。必要なものはすべて名前を変更したと思いますが、そうではありませんでした。プログラムは、質問で説明したように期待どおりに実行されませんが、エラーや警告はなく、Xcodeはコンパイルして実行するだけです。

しばらくして、ようやくサブクラスファイルを再生成してバグを修正しようとすると、古いBankDetailsものがクラス名として表示され、多くの名前付けエラーが発生します。最初はXcodeのバグだと思いました。そこで、ビルドをクリーンアップして、サブクラスファイルを再生成します。それでも、それはまだ古き良きBankDetailsです。何度か試した後、Data Model Inspectorで問題を見つけました(下のスクリーンショットを参照)。クラス名を変更すると、すべてが完全に実行されます。

道徳:常に細心の注意を払って名前を変更してください!

ここに画像の説明を入力してください

于 2012-09-29T10:28:56.613 に答える
-1

問題は=、述語文字列での演算子の使用にある可能性があります。

ドキュメントによると、LIKE演算子は文字列の比較に使用されます。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"info.name like %@",self.bankInfo.name];

ドキュメントには、述語内の関係をトラバースする例も示されているため、目的の結果を達成できるはずです。NSPredicateドキュメントから:

次のような関係の述語を作成できます。

  • 「work*」のようなgroup.name
于 2012-09-26T19:11:37.377 に答える