クラスにエラー処理を実装しようとしています。エラーの処理がどのように機能するかを完全に理解しているとは思いませんが、関数内のエラーを ( NSError *__autoreleasing *error
) として宣言するようにアドバイスされていることに気付いたので、そうしました。関数を介してエラーを渡す際に問題があります。
次の問題が発生します: 分解すると、次のように問題が発生するようです: (申し訳ありませんが、実際のコードは長すぎますが、問題にとって最も重要なものを抽出しようとしました! 私のコードの範囲に問題が含まれていることを願っています)
次のメソッドを持つObjectAがあるとします。
-(NSString *) do1: (NSString *) withstuff error:(NSError *__autoreleasing *)error{
//...
//error happens
*error = [[NSError alloc] initwithDomain: domain code: blah userinfo: infodict];
return nil;
}
-(BOOL) do2error:(NSError *__autoreleasing *)error{
NSString *doesntmatter = [self do1: @"whatever" error: error];
if (doesntmatter == nil){
return NO;
}
}
別のクラス (AppDelegate オブジェクト) で、次のように呼び出します。
ObjectA* ob1 = [[ob1 alloc] init];
NSError *errorBoom = nil;
if ([ob1 do2error:&errorBoom] == NO){
NSLog(@"error: %@",errorBoom); //---> bad access error
}
errorBoom にアクセスできなくなったようですか? 「__autoreleases」のせいでしょうか、それが実際に何を意味するのかを理解しようとしましたが、これまでのすべての説明は、私がこの分野で非常に新しいため、あまり役に立ちませんでした...これで私を助けてくれることを願っています!
編集:
わかりました、エラーを追跡したと思います。これで原因はわかったのですが、正確な理由はわかりません。「Bad Access」エラー発生の主な原因を抽出する簡単なサンプル アプリケーションを作成しました。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
NSError *errtest = nil;
BOOL testBool = [self messaroundwitherr:&errtest];
NSLog(@"Filled NSError? : %@",errtest); //<--Causes Bad Access.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
-(BOOL) giveErrornow:(NSError *__autoreleasing *)err {
NSMutableDictionary *errInfo = [[NSMutableDictionary alloc] init];
[errInfo setObject:@"I feel like giving you an error!" forKey:NSLocalizedDescriptionKey];
*err = [[NSError alloc] initWithDomain:@"nonesense"
code:0
userInfo:errInfo];
return NO;
}
-(BOOL) messaroundwitherr:(NSError *__autoreleasing *)err{
//@autoreleasepool { --> uncommenting that causes the error
return [self giveErrornow: err];
//}
}
したがって、どうやら自動解放プールをアクティブにすると、外部関数 (AppFinishLaunching...) から読み取ることができるようになる前に、err 変数の割り当てが解除されます。なぜそれが正確に起こっているのですか?「@autoreleasepool」は、使用後に変数の割り当てを解除することを知っています。元のコンテキストでは、while ループがありました。それが理由です。ここでは、理解のためだけです。では、@"autoreleasepool" はどのように機能するのでしょうか? コマンド (*__autorelease *) で実際に何が起こるか。
修正する前に、その概念を完全に理解する必要があると思います。NSError (*__autorelease *) err は、ARC の「自動解放されるオブジェクトのポインターへのポインター (そうであれば、いつ)」を定義しますか?