Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ARC & Blocks 時代の ベストプラクティスを考える
Search
Kishikawa Katsumi
May 27, 2012
Technology
8
33k
ARC & Blocks 時代の ベストプラクティスを考える
ARC & Blocks を使ったときの循環参照を避けるための現実的なサンプル。
Kishikawa Katsumi
May 27, 2012
Tweet
Share
More Decks by Kishikawa Katsumi
See All by Kishikawa Katsumi
iOSDC 2024 SMBファイル共有をSwiftで実装する
kishikawakatsumi
1
240
Enhancing Applications with Accessibility API
kishikawakatsumi
3
4.3k
Mastering SwiftSyntax
kishikawakatsumi
4
6.5k
My SwiftData Review
kishikawakatsumi
7
1.5k
Swift Expression Macros: a practical introduction
kishikawakatsumi
3
2k
Xcode Cloudの評価
kishikawakatsumi
2
1.4k
Regular expressions basics/正規表現の基本
kishikawakatsumi
7
790
家のいろいろな数値を計測する
kishikawakatsumi
4
2.3k
GitHub Actionsでテストの結果をわかりやすく表示する
kishikawakatsumi
1
1.2k
Other Decks in Technology
See All in Technology
Core Audio tapを使ったリアルタイム音声処理のお話
yuta0306
0
190
Glacierだからってコストあきらめてない? / JAWS Meet Glacier Cost
taishin
1
160
Beyond Kaniko: Navigating Unprivileged Container Image Creation
f30
0
130
さくらのIaaS基盤のモニタリングとOpenTelemetry/OSC Hokkaido 2025
fujiwara3
3
430
Tokyo_reInforce_2025_recap_iam_access_analyzer
hiashisan
0
180
タイミーのデータモデリング事例と今後のチャレンジ
ttccddtoki
6
2.4k
AIの全社活用を推進するための安全なレールを敷いた話
shoheimitani
2
510
fukabori.fm 出張版: 売上高617億円と高稼働率を陰で支えた社内ツール開発のあれこれ話 / 20250704 Yoshimasa Iwase & Tomoo Morikawa
shift_evolve
PRO
2
7.5k
Oracle Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
0
110
IPA&AWSダブル全冠が明かす、人生を変えた勉強法のすべて
iwamot
PRO
2
110
生成AI活用の組織格差を解消する 〜ビジネス職のCursor導入が開発効率に与えた好循環〜 / Closing the Organizational Gap in AI Adoption
upamune
7
5.2k
Sansanのデータプロダクトマネジメントのアプローチ
sansantech
PRO
0
140
Featured
See All Featured
Documentation Writing (for coders)
carmenintech
72
4.9k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
138
34k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
690
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.3k
A Tale of Four Properties
chriscoyier
160
23k
Embracing the Ebb and Flow
colly
86
4.7k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.4k
How STYLIGHT went responsive
nonsquared
100
5.6k
Bash Introduction
62gerente
613
210k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
Unsuck your backbone
ammeep
671
58k
Transcript
؛ࠀݾ http://kishikawakatsumi.com Twitter @k_katsumi 24/7 twenty-four seven http://d.hatena.ne.jp/KishikawaKatsumi/
ARC & Blocks ࣌ͷ ϕετϓϥΫςΟεΛߟ͑Δ
۩ମతͳίʔυ͔Β ॥ࢀরΛආ͚ΔͨΊͷ ৼΔ͍ͷҧ͍Λ࠶֬ೝ͢Δ
ࢀߟจݙ
ॻ੶ ΤΩεύʔτObjective-Cϓϩάϥϛϯά ― iOS/OS Xͷ ϝϞϦཧͱϚϧνεϨου ࡔຊҰथ http://tatsu-zine.com/books/objc
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
ARCͱ
•Automatic Reference Counting •ϝϞϦཧΛࣗಈԽ͢Δ ʢ੩తղੳʹΑͬͯίϯύΠϥ͕ࣗಈతʹอ࣋/ղ์ͷ ίʔυΛૠೖ͢Δʣ •όΠφϦޓੑ͕͋Δ ʢARCΦϯͷόΠφϦͱΦϑͷόΠφϦΛϦϯΫͰ͖Δ, ίϯύΠϧ୯ҐͰARCΛΦϯ/ΦϑͰ͖Δʣ •Weak
referencesҎ֎Mac OS X v10.6 ͱ iOS 4Ͱ ͑Δ
ARCΦϯͰBlocksΛ͏߹ ॥ࢀরΛ࡞Γ͍͢
॥ࢀরΛආ͚ΔͨΊͷ νΣοΫϦετ
•ϒϩοΫͰϒϩοΫͷݺͼग़͠ݩΛ ࢀরͯ͠Δ͔Ͳ͏͔ •ϒϩοΫΛίϐʔ͍ͯ͠Δ͔Ͳ͏͔ •ϒϩοΫͷݺͼग़͠ݩͷΦϒδΣΫτΛ อ͍࣋ͯ͠Δ͔Ͳ͏͔ •ϒϩοΫͰselfΛࢀর͍ͯ͠Δ͔Ͳ͏͔
ϒϩοΫͰϒϩοΫͷݺͼग़͠ݩΛ ࢀর͍ͯ͠Δ߹
ʢྫʣASIHTTPRequest
- (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 ΦϒδΣΫτ͕॥ࢀর
- (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 ͞Εͳ͍
- (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
- (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
- (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
ϓϥΫςΟε̍ ݁ՌΛϒϩοΫͷҾͰฦ͢
ATService *service = [[ATService alloc] init]; service.completionBlock = ^(NSString *results,
NSError *error) { if (!error) { self.tweets = results; [tableView reloadData]; } }; [service grabURLInBackground]; ݁ՌΛϒϩοΫͷҾͰฦ͢ ARC Non ARC
@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]; } ʢࢀߟʣϥούʔଆͷ࣮
ϒϩοΫΛίϐʔ͍ͯ͠Δ͔Ͳ͏͔
- (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
ATService *service = [[ATService alloc] init]; service.completionBlock = ^(NSString *results,
NSError *error) { if (!error) { self.tweets = results; [tableView reloadData]; } }; [service grabURLInBackground]; ϒϩοΫΛίϐʔ͍ͯ͠Δ ARC Non ARC
ϒϩοΫΛίϐʔͨ͠߹ ݺͼग़͠ݩΛࢀর͢Δͱ ॥ࢀর͢Δ ARC Non ARC
ϓϥΫςΟε̎ ʢͰ͖Δ͚ͩʣϒϩοΫΛ ίϐʔ͠ͳ͍
ATService *service = [[ATService alloc] init]; [service grabURLWithCompletionBlock:^(NSArray *results, NSError
*error) { self.tweets = results; [self.tableView reloadData]; [service log]; }]; ϒϩοΫΛίϐʔ͠ͳ͍ ARC Non ARC
- (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]; } ʢࢀߟʣϥούʔଆͷ࣮
ϒϩοΫͷݺͼग़͠ݩͷ ΦϒδΣΫτΛอ͍࣋ͯ͠Δ͔Ͳ͏͔
ϒϩοΫͰ selfΛࢀর͍ͯ͠Δ͔Ͳ͏͔
[service grabURLInBackgroundWithCompletionBlock:^(NSArray *results, NSError *error) { self.tweets = results; [self.tableView
reloadData]; [service log]; }]; ARC Non ARC @interface ATDetailViewController () { ATService *service; } @end ϒϩοΫͷݺͼग़͠ݩΛอ͍࣋ͯͯ͠ϒϩοΫ͕ ίϐʔ͞Εͳ͍ͳΒΩϟϓνϟ͞Εͨࣗಈม ϒϩοΫͷείʔϓΛൈ͚ͨͱ͖ʹղ์͞ΕΔ
service.completionBlock = ^(NSArray *results, NSError *error) { self.tweets = results;
[self.tableView reloadData]; [service log]; }; [service grabURLInBackground]; ARC Non ARC @interface ATDetailViewController () { ATService *service; } @end ϒϩοΫͷݺͼग़͠ݩΛอ͍࣋ͯͯ͠ɺϒϩοΫ͕ ίϐʔ͞ΕΔ߹॥ࢀরͱͳΔ
ϓϥΫςΟε̏ղܾํ๏ self Λ __weak (__unsafe_unretained) ࢦఆͷϩʔΧϧมʹೖ͢Δ
__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 ΛϩʔΧϧมʹೖͯ͠ ϩʔΧϧมΛ௨ͯ͠ΞΫηε͢Δ
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Λߋ৽͢Δ߹ʹ ॥ࢀরΛ࡞Γ͕ͪ
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 ݟམͱ͍͢͠
- (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 Λ͏)
ϓϥΫςΟε̐ delegate target actionͰ ࣮͢Δ͜ͱΛݕ౼͢Δ
Blocks ͷ͍ํ ՄಡੑͱνʔϜϝϯόʔͷ ྗྔͳͲ͍Ζ͍Ζͳ όϥϯεΛݟۃΊͯ ͍͚ΒΕΔΑ͏ʹ͍ͨ͠
ϓϥΫςΟε̑ Ϋϥεϝιουʹ͢Δ
[EPATNDAPIClient eventsWithKeyword:keyword completionBlock:^(NSArray *results, NSError *error) { if (!error) {
NSArray *events = [self saveEvents:results]; [[EPCoreDataManager sharedManager] saveContext]; } }]; Ϋϥεϝιουʹ͢Δͱ ͏΄͏͍Ζ͍Ζߟ͑ͳͯ͘ϥΫ ARC Non ARC
Tips
ෳͷϑΝΠϧʹ ίϯύΠϥΦϓγϣϯΛઃఆ͢Δʹ
Build PhasesʼCompile Sources Ͱ ෳͷϑΝΠϧΛબͯ͠...
EnterΩʔΛԡ͠·͢ɻ μϒϧΫϦοΫͰμϝ
None