Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Cocoa勉強会関西#53
Search
cockscomb
December 14, 2013
Programming
3
590
Cocoa勉強会関西#53
Key Value Observationを利用するUITableViewDataSourceについて話しました。雑談コーナーもあります。
cockscomb
December 14, 2013
Tweet
Share
More Decks by cockscomb
See All by cockscomb
jq at the Shortcuts
cockscomb
1
2k
GraphQL放談
cockscomb
4
2.1k
GraphQL Highway
cockscomb
28
8.6k
吉田を支える技術
cockscomb
0
2.4k
コーポレートサイトを静的化してAmplify Consoleにデプロイする
cockscomb
0
3.4k
ユーザインターフェイスと非同期処理
cockscomb
5
2k
GUIアプリケーションの構造と設計
cockscomb
10
10k
イカリング2におけるシングルページアプリケーション
cockscomb
2
7.6k
あなたの知らない UIKit の世界 — UITableView に UITextView を置きたい
cockscomb
1
7.5k
Other Decks in Programming
See All in Programming
宅宅自以為的浪漫:跟 AI 一起為自己辦的研討會寫一個售票系統
eddie
0
500
20251127_ぼっちのための懇親会対策会議
kokamoto01_metaps
2
430
S3 VectorsとStrands Agentsを利用したAgentic RAGシステムの構築
tosuri13
6
310
バックエンドエンジニアによる Amebaブログ K8s 基盤への CronJobの導入・運用経験
sunabig
0
160
配送計画の均等化機能を提供する取り組みについて(⽩⾦鉱業 Meetup Vol.21@六本⽊(数理最適化編))
izu_nori
0
150
ID管理機能開発の裏側 高速にSaaS連携を実現したチームのAI活用編
atzzcokek
0
220
【CA.ai #3】ワークフローから見直すAIエージェント — 必要な場面と“選ばない”判断
satoaoaka
0
240
MAP, Jigsaw, Code Golf 振り返り会 by 関東Kaggler会|Jigsaw 15th Solution
hasibirok0
0
230
Rediscover the Console - SymfonyCon Amsterdam 2025
chalasr
2
160
TUIライブラリつくってみた / i-just-make-TUI-library
kazto
1
380
生成AIを利用するだけでなく、投資できる組織へ
pospome
2
320
Rubyで鍛える仕組み化プロヂュース力
muryoimpl
0
110
Featured
See All Featured
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.6k
The Art of Programming - Codeland 2020
erikaheidi
56
14k
Balancing Empowerment & Direction
lara
5
800
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
Code Reviewing Like a Champion
maltzj
527
40k
The Invisible Side of Design
smashingmag
302
51k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.6k
How STYLIGHT went responsive
nonsquared
100
6k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.3k
Making Projects Easy
brettharned
120
6.5k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
710
Transcript
cockscomb
גࣜձࣾͯͳ Application Engineer Hatena Blog, Hatena Space cockscomb
Hatena Engineer Seminar #2 ͯͳʹ͓͚ΔϞμϯiOSΞϓϦ։ൃೖ
– @uzulla lυϥοάΞϯυυϩοϓࣦഊ͍ͬͯ͢͠%JT Γͭͭ$-*ͷDPDPB1PEΛࢍඒͨ͠ޙʹɺʮϚ εͰ৭ʑͰ͖Δ4#ศརɺ͋ͱ͜͜Μͱ͜Ͱ %O%͢Δͱόʔ͕ͷͼͨΓஔͰ͖ͯศརʂʯͬ ͯݴ͏ͷ͍͢͝IBUFOBUFDIz
– @kazuph lϞμϯʹॻ͔ͳ͔ͬͨ߹ͱॻ͍ͨ߹Λίʔ υͰൺֱͨͭ͠ͷͰઆ໌Λͯ͘͠ΕͯΔͷͰ ͍͢͝ḿΔIBUFOBUFDIz
͜Ε͕MVC™Ͱ͢
UITableViewDataSource
Bookmarks View BookmarkManager - (NSArray *)bookmarks TableViewController Refer Update
in TableViewController [[IBKMBookmarkManager sharedManager] reloadBookmarksWithBlock:^(NSError *error) { if (error) {
NSLog(@"Error: %@", error); } [self.tableView reloadData]; }];
Better Way [[IBKMBookmarkManager sharedManager] reloadBookmarksWithBlock:^(NSError *error) { if (error) {
NSLog(@"Error: %@", error); } }];
Key Value Observation
Observe [[IBKMBookmarkManager sharedManager] addObserver:self forKeyPath:@"bookmarks" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if
(object == [IBKMBookmarkManager sharedManager] && [keyPath isEqualToString:@"bookmarks"]) { NSIndexSet *indexSet = change[NSKeyValueChangeIndexesKey]; NSKeyValueChange changeKind = (NSKeyValueChange)[change[NSKeyValueChangeKindKey] integerValue]; ! NSMutableArray *indexPaths = [NSMutableArray array]; [indexSet enumerateIndexesUsingBlock:^(NSUInteger index, BOOL *stop) { [indexPaths addObject:[NSIndexPath indexPathForRow:index inSection:0]]; }]; ! [self.tableView beginUpdates]; if (changeKind == NSKeyValueChangeInsertion) { [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; } else if (changeKind == NSKeyValueChangeRemoval) { [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; } else if (changeKind == NSKeyValueChangeReplacement) { [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; } [self.tableView endUpdates]; } }
in Bookmarks Manager [[self mutableArrayValueForKey:@"bookmarks"] insertObjects:newBookmarks atIndexes:[NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, newBookmarks.count)]];
Mutable array proxy
Bookmarks View BookmarkManager - (NSArray)bookmarks TableViewController Observe Notify Update
Is it, eh?
Problems • Lightweight view controller • Copy and paste? •
Testability
The Best Way self.observerDataSource = [[ObserverTableViewDataSource alloc] initWithObserved:[IBKMBookmarkManager sharedManager] keyPath:NSStringFromSelector(@selector(bookmarks))
tableView:self.tableView superDataSource:self]; ! self.observerDataSource.configureCell = ^UITableViewCell *(UITableView *tableView, NSIndexPath *indexPath, id object) { static NSString *const CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; ! ... ! return cell; }; ! self.tableView.dataSource = self.observerDataSource;
Observer Data Source • Useful for many occasions • DRY
• Testable • Applicable to UICollectionView
This is the MVC™
References Lighter View Controllers — objc.io Key-Value Coding and Observing
— objc.io Key-Value Observing — NSHipster
ࡶஊίʔφʔ
ʰiOS Core Data పఈೖʱ • ࠷ॳͷ͘Β͍ಡ·ͳ͍͍ͯ͘ • Core Dataʹ͍͓͓ͭͯΑͦཏత •
ຊޠͷใ͋·Γͳ͍ͷͰՁ͕ߴ͍ • ϚϧνεϨουͷ͜ͱॻ͍ͯͳ͍ • ύϑΥʔϚϯεͷ͜ͱॻ͍ͯͳ͍
iOS 7 ྑ͗͢Δ • CFAutorelease() • NSArray -firstObject • TextKit
• JavaScriptCore • Others
WebView JavaScript Bridging • - webView: shouldStartLoadWithRequest: navigationType: • Cordova
• WebViewJavascriptBridge • JSContext JSContext *ctx = [self.webView valueForKeyPath: @"documentView.webView.mainFrame.javaScriptContext"]; JSValue *three = [ctx evaluateScript:@“1+2"];
ੵۃ࠾༻த http://www.hatena.ne.jp/company/staff