清洁代码:如何避免所有嵌套if / success块?

时间:2014-01-28 07:01:30

标签: objective-c ios7 coding-style

我想知道如何避免所有那些嵌套的if / success块?因此,我对如何改进/封装此架构的任何建议感到满意

- (void)findLocation {

    // Show loader.png
   [self.searchButton setImage:[UIImage imageNamed:@"loader"] forState:UIControlStateNormal];

    // Request url
    NSString *url = [NSString stringWithFormat:@"http://api.domain.com/someendpoint/"];

    // Send http request
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    [manager GET:url parameters:nil
         success:^(AFHTTPRequestOperation *operation, id responseObject) {


             // If API returned error
             if([responseObject objectForKey:@"error"]) {

                // Show an error

                // Hide loader
                [self.searchButton setImage:[UIImage imageNamed:@"some_button"] forState:UIControlStateNormal];

                // Skip everything else
                return;
            }


             // If API returned data    

             // Init location object
             Location * location = [[Location alloc] init];
             location.name = [responseObject objectForKey:@"name"];
             location.image_url = [responseObject objectForKey:@"image_url"];
             location.url = [responseObject objectForKey:@"url"];
             location.address = [responseObject objectForKey:@"address"];

             // Calculate long/lat from address (API does not provide this information
             CLGeocoder *geocoder = [[CLGeocoder alloc] init];
             [geocoder geocodeAddressString:location.address completionHandler:^(NSArray *placemarks, NSError *error) {
                 if (error) {
                     // Show error
                 } else {
                     // Save geo-location to location object 
                     CLPlacemark *place = [placemarks lastObject];
                     location.location = CLLocationCoordinate2DMake(place.location.coordinate.latitude, place.location.coordinate.longitude);

                     // Present ResultViewController
                     ResultViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"ResultView"];
                     controller.location = location;
                     controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
                     [self presentViewController:controller animated:YES completion:nil];

                     // Initialize region to monitor
                     CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:location.location radius:150.0 identifier:[[NSUUID UUID] UUIDString]];

                     // Start monitoring new region
                     [self.locationManager startMonitoringForRegion:region];

                     // Stop UpdatingLocation
                     [self.locationManager stopUpdatingLocation];

                     // Hide loader
                     [self.searchButton setImage:[UIImage imageNamed:@"some_button"] forState:UIControlStateNormal];
                 }];

             }


         }
         failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            // Show error

            // Hide loader
            [self.searchButton setImage:[UIImage imageNamed:@"some_button"] forState:UIControlStateNormal];

         }
     ];
}

2 个答案:

答案 0 :(得分:0)

Show error部分之后,从函数返回。这样,您可以将其余代码放在else子句之外。

答案 1 :(得分:0)

正如S. McConnel建议的那样,首先使用if来处理成功的场景 - 这使得代码阅读更容易。

正如zmbq建议的那样,将它包装成一个函数。

obj c中的块并不是真正的“十大”因为它们的美丽,只是与它们一起使用:)

Google的Objective C代码风格的一些提示:

http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml#Blocks

作为功能的变体:

- (void)findLocation {

// Show loader.png
[self.searchButton setImage:[UIImage imageNamed:@"loader"] forState:UIControlStateNormal];

// Request url
NSString *url = [NSString stringWithFormat:@"http://api.domain.com/someendpoint/"];

// Send http request
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:url parameters:nil
     success:^(AFHTTPRequestOperation *operation, id responseObject) {

         // If API returned data
         if([[responseObject objectForKey:@"ErrorCode"] intValue] == 0) {

            [self setupLocation:responseObject];

         // If API returned error    
         } 
        else { // Show an error

              // Hide loader
             [self.searchButton setImage:[UIImage imageNamed:@"surpriseme_button"] forState:UIControlStateNormal];
              }
           }];
        }
     }
     failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        // Hide loader
        [self.searchButton setImage:[UIImage imageNamed:@"surpriseme_button"] forState:UIControlStateNormal];

     }
 ];
}