2

文字通り返したくないので、「返す」を引用符で囲みます。にポインターからポインターへのポインターを渡す方法と同様に行いたいと思います[NSString stringWithContentsOfFile:usedEncoding:error:]

parseFiles:errorreturn nil を作成し、渡されたエラー参照に、どちらが失敗したかに応じて、最初または 2 番目のエラーが含まれるようにしたいと考えています。それはCocoaの方法のように思えますか?

編集:申し訳ありませんが、どこで問題が発生したかをもっと明確にする必要がありました。最初のパスが偽物である場合、それは私が望むように機能します。(外部でエラー インスタンスを取得し、出力します。) 最初のパスが正当である場合、以下のフィラー文字列が示すように、EXC_BAD_ACCESS.

しかし今、私はそれを修正しました。メソッド*error内で参照し、失敗したかどうかを確認するときに使用する必要があります。私はただできると思った...parseFiles:error:== nilif (error)

EDIT 2 OK、うまくいきません。私は得てEXC_BAD_ACCESSいます。エラーをチェックする条件で何が間違っているのかわかりません。

@implementation PassingError

- (id)init {
    self = [super init];

    NSError *error;
    [self parseFiles:@"/untitled.py" error:&error];

    if (error != nil) {
        NSLog(@"I failed because: %@", error);
    }
    return self;
}

// Wraps with reading errors.
- (NSString *)parseFiles:(NSString *)path error:(NSError **)error {

    NSStringEncoding enc1;
    NSString *contents1 = [NSString stringWithContentsOfFile:path
                                               usedEncoding:&enc1 error:*&error];

    // there was a read error

    // I need an asterisk here...
    if (*error != nil) {
        // ...and also one here
        NSLog(@"FIRST ERROR: %@", *error);
        return nil;
    }


    // here is where you'd do something that might cause another error,
    // I'll just try and read a second file for simplicity
    NSStringEncoding enc2;
    NSString *contents2 = [NSString stringWithContentsOfFile:@"/untitled.py"
                                               usedEncoding:&enc2 error:*&error];

    // there was a SECOND error
    if (*error != nil) {
        NSLog(@"SECOND ERROR: %@", *error);
        return nil;
    }


    // return both or whatever
    return [NSArray arrayWithObjects:contents1, contents2, nil];
}

@end
4

1 に答える 1

3

Objective-C でポインターを渡すと、混乱する可能性があります。何をする必要があるかを把握するのに苦労したことを覚えています。次のようなメソッドがある場合:

- (BOOL) saveValuesAndReturnError:(NSError **) error
{
    BOOL success = [self doSomethingImportant];
    
    if (!success && error)
    {
        // Unsuccessful and error is a valid ptr-to-ptr-to-NSError.
        
        // Basically, someone has given us the address of a (NSError *).
        // We can modify what that pointer points to here.
        *error = [NSError errorWithDomain:@"myDomain" code:100 userInfo:nil];
    }
    
    return success;
}

これは、次のように呼び出されることを意図しています。

// If the caller doesn't care that it failed:
[someObject saveValuesAndReturnError:NULL];



// Or, if the caller wants to get error information on failure
NSError *anError = nil;
BOOL success;

// pass address of our (NSError *)
success = [someObject saveValuesAndReturnError:&anError];
if (!success)
{
    // anError now points to an NSError object, despite being initialised to nil,
    // because we passed the address of our NSError ptr, the method was able to 
    // change where `anError` points to.
    NSLog (@"An error occurred while saving values: %@", anError);
}

おそらく、この場合に非常に関連性の高い読み物は、まさにこのトピックをカバーしているCIMGF ブログ投稿です。

でも...

少し前に、 などのメソッド引数を介してエラーを返すメソッドはstringWithContentsOfFile:usedEncoding:error:、成功のためにエラー引数を変更しないという保証がないことを読んだことを覚えています。つまり、メソッドが成功した場合、エラー パラメータの値に依存することはできません。特定のケースでは、次のことを行う方がよい場合があります。


- (NSString *)parseFiles:(NSString *)path error:(NSError **)error {

    NSStringEncoding enc1, enc2;
    NSError *innerError;
    NSString *contents1 = [NSString stringWithContentsOfFile:path
                                                usedEncoding:&enc1
                                                       error:&innerError];
    
    if (contents1 == nil)
    {
        if (error) *error = innerError;
        return nil;
    }

    NSString *contents2 = [NSString stringWithContentsOfFile:@"/untitled.py"
                                                usedEncoding:&enc2
                                                       error:&innerError];
    
    if (contents2 == nil)
    {
        if (error) *error = innerError;
        return nil;
    }
    
    // do whatever with contents1 and contents2
}

于 2010-05-25T21:51:38.403 に答える