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
Cocoa勉強会関西#53
Search
cockscomb
December 14, 2013
Programming
3
580
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
1.9k
GraphQL放談
cockscomb
4
2k
GraphQL Highway
cockscomb
28
8.5k
吉田を支える技術
cockscomb
0
2.3k
コーポレートサイトを静的化してAmplify Consoleにデプロイする
cockscomb
0
3.4k
ユーザインターフェイスと非同期処理
cockscomb
5
1.9k
GUIアプリケーションの構造と設計
cockscomb
10
10k
イカリング2におけるシングルページアプリケーション
cockscomb
2
7.5k
あなたの知らない UIKit の世界 — UITableView に UITextView を置きたい
cockscomb
1
7.5k
Other Decks in Programming
See All in Programming
Goで作る、開発・CI環境
sin392
0
230
WebViewの現在地 - SwiftUI時代のWebKit - / The Current State Of WebView
marcy731
0
120
Team operations that are not burdened by SRE
kazatohiei
1
310
Rails Frontend Evolution: It Was a Setup All Along
skryukov
0
140
ニーリーにおけるプロダクトエンジニア
nealle
0
830
Google Agent Development Kit でLINE Botを作ってみた
ymd65536
2
250
生成AI時代のコンポーネントライブラリの作り方
touyou
1
210
#QiitaBash MCPのセキュリティ
ryosukedtomita
1
1.3k
GitHub Copilot and GitHub Codespaces Hands-on
ymd65536
2
150
“いい感じ“な定量評価を求めて - Four Keysとアウトカムの間の探求 -
nealle
1
10k
おやつのお供はお決まりですか?@WWDC25 Recap -Japan-\(region).swift
shingangan
0
130
なんとなくわかった気になるブロックテーマ入門/contents.nagoya 2025 6.28
chiilog
1
270
Featured
See All Featured
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
Automating Front-end Workflow
addyosmani
1370
200k
Into the Great Unknown - MozCon
thekraken
40
1.9k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.3k
Optimizing for Happiness
mojombo
379
70k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.3k
Optimising Largest Contentful Paint
csswizardry
37
3.3k
Writing Fast Ruby
sferik
628
62k
Code Review Best Practice
trishagee
69
18k
Git: the NoSQL Database
bkeepers
PRO
430
65k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.5k
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