Verständnisfrage bezüglich Blocks und self

  • Verständnisfrage bezüglich Blocks und self

    ich hätte mal kurz eine Frage, und zwar wann entsteht ein retain-Cycle:

    habe hier folgenden Code

    Quellcode

    1. [[AFFnBAPIClient sharedClient] postPath:FNB_LOGIN_PATH parameters:dict success:^(AFHTTPRequestOperation *operation, id JSON) {
    2. if ([[JSON objectForKey:@"status"] isEqualToString:@"ok"]) {
    3. self.user = [NSDictionary dictionaryWithDictionary:[JSON objectForKey:@"users"]];
    4. } else {
    5. NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    6. [dict setObject:[JSON objectForKey:@"error"] forKey:@"error"];
    7. [self showAlertView:dict];
    8. }
    9. } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    10. NSLog(@"Error");
    11. }];
    Alles anzeigen



    entsteht jetzt bei self.user ein retain-Cycle oder nur bei self showAlertView oder doch bei beiden?
    [window close]
  • Sollte das nicht gleichgültig sein oder findest du manche Retain-Cycles weniger schlimm?

    Es entsteht bei jeder Verwendung von self im Closure, wozu auch der Zugriff auf Instanzvariablen von self gehört.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • hmmm, das verwirrt mich gerade etwas, also sobald ich self doSomething oder self.irgendwas in einem Block verwende entsteht ein retain-Cycle? Weil in der Apple-Doku zu Blocks ja auch im Closure self.irgendwas benutzt wird oder verwechsle ich da was?

    Quellcode

    1. - (IBAction)animateView:(id)sender {
    2. CGRect cacheFrame = self.imageView.frame;
    3. [UIView animateWithDuration:1.5 animations:^{
    4. CGRect newFrame = self.imageView.frame;
    5. newFrame.origin.y = newFrame.origin.y + 150.0;
    6. self.imageView.frame = newFrame;
    7. self.imageView.alpha = 0.2;
    8. }
    9. completion:^ (BOOL finished) {
    10. if (finished) {
    11. // Revert image view to original.
    12. sleep(3);
    13. self.imageView.frame = cacheFrame;
    14. self.imageView.alpha = 1.0;
    15. }
    16. }];
    17. }
    Alles anzeigen
    [window close]
  • Der retain-Cycle entsteht, wenn Du den block auch in der durch self referenzierten Klasse speicherst. Mit ARC kannst Du das folgendermaßen vermeiden:

    Quellcode

    1. __weak TypDeinerKlasse *weakPointer = self;
    2. ^(einBlock)(void) {
    3. weakPointer.property = ...
    4. }
    Schau Dir die ARC und Block-Session Videos der letzten WWDC an. Gruß, Markus
  • Markus Müller schrieb:

    Der retain-Cycle entsteht, wenn Du den block auch in der durch self referenzierten Klasse speicherst.

    Mit ARC kannst Du das folgendermaßen vermeiden:

    Quellcode

    1. __weak TypDeinerKlasse *weakPointer = self;
    2. ^(einBlock)(void) {
    3. weakPointer.property = ...
    4. }

    Schau Dir die ARC und Block-Session Videos der letzten WWDC an.

    Gruß, Markus
    ahhh, nun verstehe ich, wenn es sich also um einen ganz normalen Methodenaufruf aus einer anderen Klasse heraus handelt, ist self ja nicht die Klasse die den Block deklariert
    [window close]
  • uniique schrieb:

    hmmm, das verwirrt mich gerade etwas, also sobald ich self doSomething oder self.irgendwas in einem Block verwende entsteht ein retain-Cycle? Weil in der Apple-Doku zu Blocks ja auch im Closure self.irgendwas benutzt wird oder verwechsle ich da was?

    Quellcode

    1. - (IBAction)animateView:(id)sender {
    2. CGRect cacheFrame = self.imageView.frame;
    3. [UIView animateWithDuration:1.5 animations:^{
    4. CGRect newFrame = self.imageView.frame;
    5. newFrame.origin.y = newFrame.origin.y + 150.0;
    6. self.imageView.frame = newFrame;
    7. self.imageView.alpha = 0.2;
    8. }
    9. completion:^ (BOOL finished) {
    10. if (finished) {
    11. // Revert image view to original.
    12. sleep(3);
    13. self.imageView.frame = cacheFrame;
    14. self.imageView.alpha = 1.0;
    15. }
    16. }];
    17. }
    Alles anzeigen

    Scherzkeks, den Block musst du natürlich auch umgekehrt aus self referenzieren (etwa über eine Property).
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?