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
160
Enhancing Applications with Accessibility API
kishikawakatsumi
3
3.2k
Mastering SwiftSyntax
kishikawakatsumi
4
5.3k
My SwiftData Review
kishikawakatsumi
7
1.4k
Swift Expression Macros: a practical introduction
kishikawakatsumi
3
1.8k
Xcode Cloudの評価
kishikawakatsumi
2
1.2k
Regular expressions basics/正規表現の基本
kishikawakatsumi
7
720
家のいろいろな数値を計測する
kishikawakatsumi
4
2.2k
GitHub Actionsでテストの結果をわかりやすく表示する
kishikawakatsumi
1
1k
Other Decks in Technology
See All in Technology
TypeScriptの次なる大進化なるか!? 条件型を返り値とする関数の型推論
uhyo
2
1.7k
アジャイルチームがらしさを発揮するための目標づくり / Making the goal and enabling the team
kakehashi
3
140
Oracle Cloud Infrastructureデータベース・クラウド:各バージョンのサポート期間
oracle4engineer
PRO
28
13k
Lexical Analysis
shigashiyama
1
150
BLADE: An Attempt to Automate Penetration Testing Using Autonomous AI Agents
bbrbbq
0
320
【Startup CTO of the Year 2024 / Audience Award】アセンド取締役CTO 丹羽健
niwatakeru
0
1.3k
初心者向けAWS Securityの勉強会mini Security-JAWSを9ヶ月ぐらい実施してきての近況
cmusudakeisuke
0
130
AI前提のサービス運用ってなんだろう?
ryuichi1208
8
1.4k
OS 標準のデザインシステムを超えて - より柔軟な Flutter テーマ管理 | FlutterKaigi 2024
ronnnnn
0
230
100 名超が参加した日経グループ横断の競技型 AWS 学習イベント「Nikkei Group AWS GameDay」の紹介/mediajaws202411
nikkei_engineer_recruiting
1
170
Python(PYNQ)がテーマのAMD主催のFPGAコンテストに参加してきた
iotengineer22
0
510
Application Development WG Intro at AppDeveloperCon
salaboy
0
190
Featured
See All Featured
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
24k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.4k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Reflections from 52 weeks, 52 projects
jeffersonlam
346
20k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
4
370
Unsuck your backbone
ammeep
668
57k
GraphQLとの向き合い方2022年版
quramy
43
13k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
Ruby is Unlike a Banana
tanoku
97
11k
Speed Design
sergeychernyshev
25
620
Statistics for Hackers
jakevdp
796
220k
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