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 Touch: The Good, The Bad and The Ugly
Search
Chris Eidhof | @chriseidhof
December 16, 2013
Programming
2
190
Cocoa Touch: The Good, The Bad and The Ugly
This is a talk I gave at Alt Tech Talks London, as a try out for MCE.
Chris Eidhof | @chriseidhof
December 16, 2013
Tweet
Share
More Decks by Chris Eidhof | @chriseidhof
See All by Chris Eidhof | @chriseidhof
Dutch FP Day 2015
chriseidhof
2
380
Tiny Networking in Swift
chriseidhof
2
19k
Functional Swift - Brooklyn
chriseidhof
3
1.2k
Functional Swift - SF
chriseidhof
6
26k
Functional Swift
chriseidhof
6
1.3k
Functional Swift
chriseidhof
1
150
Functional Programming in Swift
chriseidhof
40
19k
Lighter View Controllers
chriseidhof
4
200
Parsing with Blocks
chriseidhof
2
230
Other Decks in Programming
See All in Programming
複雑化したリポジトリをなんとかした話 pipenvからuvによるモノレポ構成への移行
satoshi256kbyte
1
760
ネイティブ製ガントチャートUIを作って学ぶUICollectionViewLayoutの威力
jrsaruo
0
130
なぜGoのジェネリクスはこの形なのか? Featherweight Goが明かす設計の核心
ryotaros
7
1k
ててべんす独演会〜Flowの全てを語ります〜
tbsten
1
220
CSC509 Lecture 06
javiergs
PRO
0
240
dynamic!
moro
9
6.4k
ABEMAモバイルアプリが Kotlin Multiplatformと歩んだ5年 ─ 導入と運用、成功と課題 / iOSDC 2025
akkyie
0
320
開発生産性を上げるための生成AI活用術
starfish719
1
170
止められない医療アプリ、そっと Swift 6 へ
medley
1
120
大規模アプリのDIフレームワーク刷新戦略 ~過去最大規模の並行開発を止めずにアプリ全体に導入するまで~
mot_techtalk
0
380
なぜあの開発者はDevRelに伴走し続けるのか / Why Does That Developer Keep Running Alongside DevRel?
nrslib
3
370
After go func(): Goroutines Through a Beginner’s Eye
97vaibhav
0
230
Featured
See All Featured
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
What's in a price? How to price your products and services
michaelherold
246
12k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.2k
The Power of CSS Pseudo Elements
geoffreycrofte
79
6k
The Language of Interfaces
destraynor
162
25k
Typedesign – Prime Four
hannesfritz
42
2.8k
Visualization
eitanlees
148
16k
Music & Morning Musume
bryan
46
6.8k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Designing for Performance
lara
610
69k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
A Tale of Four Properties
chriscoyier
160
23k
Transcript
None
Cocoa Touch The Good, The Bad and The Ugly Chris
Eidhof
Cocoa Touch The Ugly, The Good and The Bad Chris
Eidhof
commit c416c1d259bddaa74833e6df5acd770f85622293 Author: Chris Eidhof <
[email protected]
> Date: Wed Jan 7
11:54:34 2009 +0100 Empty project
None
None
I thought I was a pretty good programmer
I knew PHP, Ruby and Haskell
How hard can it be?
None
The ugly
Example code @interface HiscoreTableViewCell : UITableViewCell { IBOutlet UIImageView *badge;
IBOutlet UILabel *badgeTitle; IBOutlet UILabel *name1; IBOutlet UILabel *name2; IBOutlet UILabel *name3; IBOutlet UILabel *position1; IBOutlet UILabel *position2; IBOutlet UILabel *position3; IBOutlet UILabel *score1; IBOutlet UILabel *score2; IBOutlet UILabel *score3; }
Example code (continued) @property (nonatomic,readonly) UIImageView* badge; @property (nonatomic,readonly) UILabel
*badgeTitle; @property (nonatomic,readonly) UILabel *name1; @property (nonatomic,readonly) UILabel *name2; @property (nonatomic,readonly) UILabel *name3; @property (nonatomic,readonly) UILabel *position1; @property (nonatomic,readonly) UILabel *position2; @property (nonatomic,readonly) UILabel *position3; @property (nonatomic,readonly) UILabel *score1; @property (nonatomic,readonly) UILabel *score2; @property (nonatomic,readonly) UILabel *score3;
Example code (continued) @synthesize badge; @synthesize badgeTitle; @synthesize name1; @synthesize
name2; @synthesize name3; @synthesize position1; @synthesize position2; @synthesize position3; @synthesize score1; @synthesize score2; @synthesize score3;
There's more
//TODO: as of here, it is completely broken if ([gameView
superview] != nil) { [[SoundBoard sharedSoundBoard] startMenuTune]; [menuViewController viewWillAppear:YES]; [gameViewController viewWillDisappear:YES]; [gameView removeFromSuperview]; [gameViewController viewDidDisappear:YES]; [menuViewController viewDidAppear:YES]; } else {
NSURL *cgiUrl = [NSURL URLWithString:POST_SCORE_URL]; NSMutableURLRequest *p = [NSMutableURLRequest requestWithURL:cgiUrl];
[p setTimeoutInterval:4]; [p setHTTPMethod:@"POST"]; [p setHTTPBody:requestData]; NSURLResponse *response = nil; NSError *error = nil; NSData *responseData = [NSURLConnection sendSynchronousRequest:p returningResponse:&response error:&error];
Memory Management 1. Add an instance variable 2. Add a
property 3. Add a synthesize 4. Add a dealloc call
Memory Management 1. Add an instance variable 2. Add a
property 3. Add a synthesize 4. Add a dealloc call
Memory Management
Animations [UIView beginAnimations:@"GameOver" context:NULL]; [UIView setAnimationDuration:0.3]; [UIView setAnimationRepeatCount:2]; [UIView setAnimationRepeatAutoreverses:YES];
// Call animateOtherStuff when the animation is done [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector: @selector(afterGameOverAnimation:finished:context:)];
Animations 2013 [UIView animateWithDuration:0.3 animations:^{ timesUp.alpha = 1; } completion:^(BOOL
finished) { [self.milkGlass removeFromSuperview]; }]
None
The Good
If there's only one thing you'll remember Write code for
the person after you
▸ Write a lot of code ▸ Work with other
people ▸ Write articles ▸ Read books and code
Write a lot of code ▸ Lots of production code
▸ Lots of throwaway code
Throwaway code
Collaborate ▸ With people who are better than you ▸
Or who aren't better than you
Write Forces you to think.
Absolute Knowledge
Perceived Knowledge
Strive to become better
Ship
Frameworks
2013 ▸ Use ARC ▸ Use properties
Core Data
What prevents me from using Core Data at this point
is my concern for scalability and performance. It’s possible I’m just being thick-headed. — Brent Simmons, 27 Sep 2013
So last weekend I switched from SQLite/FMDB to Core Data.
This may come as a surprise. — Brent Simmons, 05 Oct 2013
None
Core Data ▸ Relationships ▸ Batching ▸ NSFetchedResultsControlle r ▸
Speed of use
Code style
My model was the NSURLConnectionDelegate Model should not know about
the webservice
Using NSDictionary everywhere Create value objects
Value Objects @interface Person : NSObject @property (nonatomic,copy,readonly) NSString* name;
@property (nonatomic,strong,readonly) NSDate* birthDate; @property (nonatomic,readonly) NSUInteger numberOfKids; - (instancetype)initWithName:(NSString*)name birthDate:(NSDate*)birthDate numberOfKids:(NSUInteger)numberOfKids; @end
Immutable Objects Use lots of them.
Deep code paths - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { if (alertState
== submitScore && game.score > 0) { // 20 lines if (result != nil && [resultKeys containsObject:@"position"] && [resultKeys containsObject:@"neededPoints"] && [resultKeys containsObject:@"deviceHighscore"] && [resultKeys containsObject:@"personalHighscore"]) { // 10 lines if (position == 1) {
Deep code paths Pull out things into separate, well-named methods
Building everything in code Use Interface Builder
Writing fast code Write clear code, only optimize after measuring.
None
Tips and Tricks
Initializers [[HiscoresViewController alloc] initWithNibName:@"HiscoresView" bundle:nil]
Initializers // In HiscoresViewController.m - (id)init { self = [super
initWithNibName:@"HiscoresView" bundle:nil]; if (self) { } return self; }
Use constants if (buttonIndex == 0)
Use constants if (buttonIndex == StartButton)
Pull out variable names if ([game state] == running ||
self.trainingMode)
Pull out variable names BOOL shouldPauseGame = [game state] ==
running || self.trainingMode; if (shouldPauseGame)
Pulling out protocols For example: UITableViewDataSource
@interface FetchedResultsControllerDataSource : NSObject <UITableViewDataSource, NSFetchedResultsControllerDelegate>
- (NSInteger)numberOfSectionsInTableView:(UITableView*)t { return self.fetchedResultsController.sections.count; }
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)sectionIndex { id<NSFetchedResultsSectionInfo> section; section = self.frc.sections[sectionIndex]; return
section.numberOfObjects; }
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)ip { id object = [self objectAtIndexPath:indexPath]; id
cell = [tableView dequeueReusableCellWithIdentifier:ruI forIndexPath:ip]; [self.delegate configureCell:cell withObject:object]; return cell; }
Write small files I aim for a 100 line limit
Write small files 154 ./ViewControllers/THUserPrioritiesViewController.m 154 ./ViewControllers/THZoomingNavigationController.m 155 ./Extensions/NSArray+Extensions.m 155
./Extensions/UIView+Extensions.m 168 ./Controllers/THPriorityTimelineCollectionController.m 179 ./Controllers/THUserScreenInstancesController.m 183 ./ViewControllers/THRootViewController.m 183 ./ViewControllers/THScreenInstanceViewController.m 185 ./Model/User+Extensions.m 192 ./ViewControllers/THEditPriorityViewController.m 221 ./ViewControllers/THScreeningBarViewController.m 243 ./Views/THTimeLineView.m 263 ./ViewControllers/THCardsViewController.m 279 ./Views/THSkillboxView.m
Write small files find . -name "*.m" -exec wc -l
"{}" \; | sort -n
Keep your view controllers light This is the least reusable
code you'll write
Use protocols instead of inheritance
None
The Bad
None
None
About me ▸ @chriseidhof ▸ http://www.objc.io ▸ http://chris.eidhof.nl
Questions?