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
210
Enhancing Applications with Accessibility API
kishikawakatsumi
3
3.7k
Mastering SwiftSyntax
kishikawakatsumi
4
5.8k
My SwiftData Review
kishikawakatsumi
7
1.4k
Swift Expression Macros: a practical introduction
kishikawakatsumi
3
1.9k
Xcode Cloudの評価
kishikawakatsumi
2
1.3k
Regular expressions basics/正規表現の基本
kishikawakatsumi
7
750
家のいろいろな数値を計測する
kishikawakatsumi
4
2.2k
GitHub Actionsでテストの結果をわかりやすく表示する
kishikawakatsumi
1
1.1k
Other Decks in Technology
See All in Technology
Apache Iceberg Case Study in LY Corporation
lycorptech_jp
PRO
0
350
30→150人のエンジニア組織拡大に伴うアジャイル文化を醸成する役割と取り組みの変化
nagata03
0
200
AI自体のOps 〜LLMアプリの運用、AWSサービスとOSSの使い分け〜
minorun365
PRO
9
750
Autonomous Database Serverless 技術詳細 / adb-s_technical_detail_jp
oracle4engineer
PRO
17
45k
1行のコードから社会課題の解決へ: EMの探究、事業・技術・組織を紡ぐ実践知 / EM Conf 2025
9ma3r
12
4.4k
サバイバルモード下でのエンジニアリングマネジメント
konifar
8
1.7k
目標と時間軸 〜ベイビーステップでケイパビリティを高めよう〜
kakehashi
PRO
8
860
JAWS FESTA 2024「バスロケ」GPS×サーバーレスの開発と運用の舞台裏/jawsfesta2024-bus-gps-serverless
ma2shita
3
280
OPENLOGI Company Profile for engineer
hr01
1
20k
AIエージェント元年@日本生成AIユーザ会
shukob
1
240
What's new in Go 1.24?
ciarana
1
110
AIエージェント入門
minorun365
PRO
32
19k
Featured
See All Featured
The Invisible Side of Design
smashingmag
299
50k
For a Future-Friendly Web
brad_frost
176
9.6k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.1k
Site-Speed That Sticks
csswizardry
4
410
Rails Girls Zürich Keynote
gr2m
94
13k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
10
520
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
30
2.2k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
100
18k
Done Done
chrislema
182
16k
Unsuck your backbone
ammeep
669
57k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7.1k
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