Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ARC & Blocks 時代の ベストプラクティスを考える

ARC & Blocks 時代の ベストプラクティスを考える

ARC & Blocks を使ったときの循環参照を避けるための現実的なサンプル。

Avatar for Kishikawa Katsumi

Kishikawa Katsumi

May 27, 2012
Tweet

More Decks by Kishikawa Katsumi

Other Decks in Technology

Transcript

  1. Apple ެࣜυΩϡϝϯτ Transitioning to ARC Release Notes http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html ϒϩοΫϓϩάϥϛϯάτϐοΫ https://developer.apple.com/jp/devcenter/ios/library/documentation/Blocks.pdf%2FBlocks.pdf&ei=5ua_T_PnAa6CmQWB-dyiCg&usg=AFQjCNEB7EtpLn4Qt4N22nDrqs33gy1orA

    Clang ެࣜυΩϡϝϯτ Automatic Reference Counting http://clang.llvm.org/docs/AutomaticReferenceCounting.html ninjinkun ͷεϥΠυ iOSͱAutomatic Reference Countingʹ͍ͭͯൃද͠·ͨ͠ http://ninjinkun.hatenablog.com/entry/2011/11/19/171246
  2. - (void)grabURLInBackground { NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"]; ASIHTTPRequest *request

    = [ASIHTTPRequest requestWithURL:url]; [request setCompletionBlock:^ { NSString *responseString = [request responseString]; // ŋŋŋ }]; [request setFailedBlock:^ { NSError *error = [request error]; // ŋŋŋ }]; [request startAsynchronous]; } ARC Non ARC request ΦϒδΣΫτ͕॥؀ࢀর
  3. - (void)grabURLInBackground { NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"]; __block ASIHTTPRequest

    *request = [ASIHTTPRequest requestWithURL:url]; [request setCompletionBlock:^ { NSString *responseString = [request responseString]; // ŋŋŋ }]; [request setFailedBlock:^ { NSError *error = [request error]; // ŋŋŋ }]; [request startAsynchronous]; } http://allseeing-i.com/ASIHTTPRequest/How-to-use ARC Non ARC ARC͕ແޮͷ৔߹͸ __block ͕ࢦఆ͞Εͨ ΦϒδΣΫτ͸ retain ͞Εͳ͍
  4. - (void)grabURLInBackground { NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"]; __block ASIHTTPRequest

    *request = [ASIHTTPRequest requestWithURL:url]; [request setCompletionBlock:^ { // Use when fetching text data NSString *responseString = [request responseString]; // ŋŋŋ request = nil; }]; [request setFailedBlock:^ { NSError *error = [request error]; // ŋŋŋ request = nil; }]; [request startAsynchronous]; } ARC Non ARC
  5. - (void)grabURLInBackground { NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"]; __weak ASIHTTPRequest

    *request = [ASIHTTPRequest requestWithURL:url]; [request setCompletionBlock:^ { // Use when fetching text data NSString *responseString = [request responseString]; // ŋŋŋ }]; [request setFailedBlock:^ { NSError *error = [request error]; // ŋŋŋ }]; [request startAsynchronous]; } ARC Non ARC
  6. - (void)grabURLInBackground { NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"]; __unsafe_unretained ASIHTTPRequest

    *request = [ASIHTTPRequest requestWithURL:url]; [request setCompletionBlock:^ { // Use when fetching text data NSString *responseString = [request responseString]; // ŋŋŋ }]; [request setFailedBlock:^ { NSError *error = [request error]; // ŋŋŋ }]; [request startAsynchronous]; } ARC Non ARC
  7. ATService *service = [[ATService alloc] init]; service.completionBlock = ^(NSString *results,

    NSError *error) { if (!error) { self.tweets = results; [tableView reloadData]; } }; [service grabURLInBackground]; ݁ՌΛϒϩοΫͷҾ਺Ͱฦ͢ ARC Non ARC
  8. @implementation ATService @synthesize completionBlock; - (void)grabURLInBackground { NSURL *url =

    [NSURL URLWithString:@"http://allseeing-i.com"]; __weak ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; [request setCompletionBlock:^{ NSArray *results = [request.responseData objectFromJSONData]; if (completionBlock) { completionBlock(responseString, nil); } }]; [request setFailedBlock:^{ NSError *error = [request error]; if (completionBlock) { completionBlock(nil, error); } }]; [request startAsynchronous]; } ʢࢀߟʣϥούʔଆͷ࣮૷
  9. - (void)grabURLInBackground { NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"]; __weak ASIHTTPRequest

    *request = [ASIHTTPRequest requestWithURL:url]; [request setCompletionBlock:^ { // Use when fetching text data NSString *responseString = [request responseString]; // ŋŋŋ }]; [request setFailedBlock:^ { NSError *error = [request error]; // ŋŋŋ }]; [request startAsynchronous]; } ARC ϒϩοΫΛίϐʔ͍ͯ͠Δ Non ARC
  10. ATService *service = [[ATService alloc] init]; service.completionBlock = ^(NSString *results,

    NSError *error) { if (!error) { self.tweets = results; [tableView reloadData]; } }; [service grabURLInBackground]; ϒϩοΫΛίϐʔ͍ͯ͠Δ ARC Non ARC
  11. ATService *service = [[ATService alloc] init]; [service grabURLWithCompletionBlock:^(NSArray *results, NSError

    *error) { self.tweets = results; [self.tableView reloadData]; [service log]; }]; ϒϩοΫΛίϐʔ͠ͳ͍ ARC Non ARC
  12. - (void)grabURLInBackgroundWithCompletionBlock:(ATServiceResultsBlock)block { NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"]; __weak ASIHTTPRequest

    *request = [ASIHTTPRequest requestWithURL:url]; [request setCompletionBlock:^{ NSString *responseString = [request responseString]; if (block) { block(responseString, nil); } }]; [request setFailedBlock:^{ NSError *error = [request error]; if (block) { block(nil, error); } }]; [request startAsynchronous]; } ʢࢀߟʣϥούʔଆͷ࣮૷
  13. [service grabURLInBackgroundWithCompletionBlock:^(NSArray *results, NSError *error) { self.tweets = results; [self.tableView

    reloadData]; [service log]; }]; ARC Non ARC @interface ATDetailViewController () { ATService *service; } @end ϒϩοΫͷݺͼग़͠ݩΛอ͍࣋ͯͯ͠΋ϒϩοΫ͕ ίϐʔ͞Εͳ͍ͳΒΩϟϓνϟ͞Εͨࣗಈม਺͸ ϒϩοΫͷείʔϓΛൈ͚ͨͱ͖ʹղ์͞ΕΔ
  14. service.completionBlock = ^(NSArray *results, NSError *error) { self.tweets = results;

    [self.tableView reloadData]; [service log]; }; [service grabURLInBackground]; ARC Non ARC @interface ATDetailViewController () { ATService *service; } @end ϒϩοΫͷݺͼग़͠ݩΛอ͍࣋ͯͯ͠ɺϒϩοΫ͕ ίϐʔ͞ΕΔ৔߹͸॥؀ࢀরͱͳΔ
  15. __weak ATDetailViewController *me = self; service.completionBlock = ^(NSArray *results, NSError

    *error) { me.tweets = results; [me.tableView reloadData]; [me.service log]; }; [service grabURLInBackground]; ARC Non ARC @interface ATDetailViewController () { ATService *service; } @end ॥؀ࢀরΛආ͚ΔͨΊʹ self ΛϩʔΧϧม਺ʹ୅ೖͯ͠ ϩʔΧϧม਺Λ௨ͯ͠ΞΫηε͢Δ
  16. UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button setTitle:@"Show ActionSheet" forState:UIControlStateNormal]; [button

    addEventHandler:^(id sender) { UIActionSheet *actionSheet = [UIActionSheet actionSheetWithTitle:@"Title"]; [actionSheet setCancelButtonIndex:[actionSheet addButtonWithTitle:@"Close"]]; [actionSheet showInView:self.view]; } forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; ARC Non ARC BlocksKit ͷ UIKit ֦ுͳͲ ίʔϧόοΫͰUIΛߋ৽͢Δ৔߹ʹ ॥؀ࢀরΛ࡞Γ͕ͪ
  17. ATDetailViewController __weak *me = self; UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    [button setTitle:@"Show ActionSheet" forState:UIControlStateNormal]; [button addEventHandler:^(id sender) { UIActionSheet *actionSheet = [UIActionSheet actionSheetWithTitle:@"Title"]; [actionSheet setCancelButtonIndex:[actionSheet addButtonWithTitle:@"Close"]]; [actionSheet showInView:self.view]; } forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; ARC Non ARC self Λ͍ͬͨΜ weak ͳϩʔΧϧม਺ʹ୅ೖ͢Δɻ ӈล΍Ҿ਺ʹग़ݱ͢Δ self ͸ݟམͱ͠΍͍͢
  18. - (void)settingsButtonClicked:(id)sender { __unsafe_unretained TTTickerWindowController *me = self; settingsViewController =

    [[TTSettingsWindowController alloc] init]; settingsViewController.settings = settings; [settingsViewController sheetModalForWindow:self.window completionHandler:^(TTTickerSettings *result) { me.settings = result; me.tickerViewController.settings = result; if (me.settings.floatingWindow) { [me.window setLevel:CGShieldingWindowLevel() + 1]; } else { [me.window setLevel:NSNormalWindowLevel]; } }]; } ARC Non ARC Mac ͷ৔߹ɺLionҎ্Ͱ΋ __weak ࢦఆͷͰ͖ͳ͍ Ϋϥε͕͚ͬ͜͏͋Δ (__unsafe_unretained Λ࢖͏)
  19. [EPATNDAPIClient eventsWithKeyword:keyword completionBlock:^(NSArray *results, NSError *error) { if (!error) {

    NSArray *events = [self saveEvents:results]; [[EPCoreDataManager sharedManager] saveContext]; } }]; Ϋϥεϝιουʹ͢Δͱ ࢖͏΄͏͸͍Ζ͍Ζߟ͑ͳͯ͘ϥΫ ARC Non ARC