2016-05-12 11 views
0

私はiOSアプリケーションの開発を学んでいますが、今はObjective-Cソースコードを読んでいます。Objective-Cブロックは返されず、ブロック内で自己呼び出されますか?

これは、ユーザープロファイルを取得する方法です。

+ (void)getProfile:(void (^)(NSString *message))completion { 
    NSDictionary *dic = @{@"module":@"profile"}; 
    [[self defaultManager] POST:KBaseUrl parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject) { 
     if ([self jsonOKForResponseObject:responseObject] && [self checkLogin:responseObject]) { 
      [ProfileManager sharedInstance].rank = responseObject[@"Variables"][@"space"][@"group"][@"grouptitle"]; 
      [ProfileManager sharedInstance].credit = responseObject[@"Variables"][@"space"][@"credits"]; 
      [ProfileManager sharedInstance].gender = responseObject[@"Variables"][@"space"][@"gender"]; 
      completion(nil); 
     } else { 
      completion(@"fail"); 
     } 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     completion(@"fail"); 
    }]; 
} 

私の質問はブロックcompletionです。

ブロックvoidを返し、NSStringパラメータを受け取るとします。

ブロック内でcompletion(nil)は何を意味しますか?

ブロックcompletionはそれを自己呼び出しし、パラメータとしてnilを送信することを意味しますか?

これは、パラメータのタイプと一致しませんNSString*

私はObjCのblockについてよく知らないです。誰もヒントを与えることができますか?

+1

はい、あなたは正しいです。自身を呼び出し、nilをパラメータとして送信し、NSStringパラメータと競合しません。 NSStringのパラメータにnilを渡すだけです。 –

+0

FYI - 'completion(xxx)'へのすべての呼び出しは、 'if(completion)completion(xxx);'に変更する必要があります。これは、 'getProfile:'の呼び出しが 'nil'を' completion'パラメータに渡す場合に発生します。 – rmaddy

+0

if(完了)を使用する理由は何ですか?もし条件付きで使用せずにnilをparamとして渡すと、どんな害が起こるのですか?@rmaddy –

答えて

1

はい、あなたは正しいです。それ自身を呼び出し、nilをパラメータとして送信し、NSStringパラメータと競合しません。 nilNSStringパラメータに渡すだけです。あなたが好きな上記のメソッドを呼び出すことができ

[YourClass getProfile:^(NSString *message) { 

     //message will be nill if you pass completion(nil); 
}]; 

あなたが完了ブロックでnillを渡すときに、上記のメソッド呼び出しのメッセージがゼロになります!

完了ブロックは、あなたのメソッドの呼び出しが完了したことを通知することであり、この時点であなたはその方法は、特定のparamteresを通過させることができ、私たちはあなたの方法を検討している場合:

+ (void)getProfile:(void (^)(NSString *message))completion { 
    NSDictionary *dic = @{@"module":@"profile"}; 
    [[self defaultManager] POST:KBaseUrl parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject) { 
     if ([self jsonOKForResponseObject:responseObject] && [self checkLogin:responseObject]) { 
      ..... 
      completion(@"hey sucess"); 
     } else { 
      completion(@"if loop failed"); 
     } 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     completion(@"some error occured"); 
    }]; 
} 

と呼び出しますこの方法はGetProfile:

[YourClass getProfile:^(NSString *message) { 

     //Execution will reach here when the method call for getPRofile is complete and you have a result which you just sent through the completion block as a parameter which is a string and is waiting for you to process. 

     //you can do more from here 
     if([message isEqualToString:@"hey success"]){ 
       //do something 
     } 

      if([message isEqualToString:@"if loop failed"]){ 
       //do something 
     } 
     if([message isEqualToString:@"some error occured"]){ 
       //do something 
     } 
}]; 

@rmaddyコメントを1として、常に状況の成功を示すか、変更/ローカライズ得ることができた文字列として文字列に依存するのではなく失敗するBOOLを使用することをお勧めしIIS。文字列を使用して、エラーの詳細な説明を取得します。 だからあなたのブロックは次のようになります。

+ (void)getProfile:(void (^)(BOOL status,NSString *message))completion { 

     ..... 
     completion(YES,@"hey success"); 

} 

、あなたが「好き、それを呼び出すことができます。

[YourClass getProfile:^(BOOL status, NSString *message) { 

     if(status){ 
       //get the success message 
     }else{ 
       //get the fail message 
     } 

    }]; 
+0

私は前に誤解があったと思います。私は 'NSDictionary * dic = ...}];}'はメソッド 'getProfile:'の本体であり、ブロック 'completion'の本体であると思いました。あなたの答えを聞いた後、私は別の質問を思い付いた:ブロック '完了'は体を持っていないはずですか?ブロックの体はどこですか?私はブロックが体なしで何をすべきか分からないと思う? –

+0

ブロックは、多くの形式で使用できます。それらは、メソッドのパラメータとしてlocalvariableというプロパティとして使用できます。メソッドでblockをパラメーターとして使用すると、その本体は呼び出すメソッドに入ります。私の答えでは、ブロック本体は[YourClass getProfile:^(NSString * message){// body frm here @ penguin-penpen –

+0

のgetProfileメソッドのブロックで別のメソッドを呼び出しています。これは完成ブロック本体とはみなされません。 [[self defaultManager] POST:KBaseUrlパラメータ.....は、失敗ブロックを持つ別のメソッドです! –

0

ブロックは次のようにタイプの多くを持っていた: - :

returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...}; 
    As a property: 

@property (nonatomic, copy, nullability) returnType (^blockName)(parameterTypes); 
ローカル変数として

メソッドパラメータとして:

- (void)someMethodThatTakesABlock:(returnType (^nullability)(parameterTypes))blockName; 
typedefのよう

[someObject someMethodThatTakesABlock:^returnType (parameters) {...}]; 

:メソッド呼び出しの引数として

typedef returnType (^TypeName)(parameterTypes); 
TypeName blockName = ^returnType(parameters) {...}; 

は、ブロックが何も返さないhere

0

完成からそれについての詳細を読みます。これは実行されるコードの一部です。それはすべてです。あなたはそれを呼び出す場所を入力することができますが、他の場所で結果を使用することができます。

[MyClassのはGetProfile::^(NSStringの*メッセージ){

//書き込みコードが実行されるべきはGetProfile

NSStringのは、*メッセージは、あなたのようにあなたの関数はGetProfileを呼び出すようにするとき、あなたのブロックのために入力され、関数はジョブを終了し、ここにメッセージを送信します。
}];

[MyClass getProfile:nil];

このように使用すると、getProfileがジョブを終了したときに何もしない方がよいでしょう。

おそらくネットワーク管理者の機能の完了ブロックを、作成したものと混在させることになります。

関連する問題