Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Cocoa Touch: The Good, The Bad and The Ugly
Search
Chris Eidhof | @chriseidhof
December 16, 2013
Programming
220
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
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
More Decks by Chris Eidhof | @chriseidhof
See All by Chris Eidhof | @chriseidhof
Dutch FP Day 2015
chriseidhof
2
420
Tiny Networking in Swift
chriseidhof
2
19k
Functional Swift - Brooklyn
chriseidhof
3
1.3k
Functional Swift - SF
chriseidhof
6
26k
Functional Swift
chriseidhof
6
1.3k
Functional Swift
chriseidhof
1
180
Functional Programming in Swift
chriseidhof
40
19k
Lighter View Controllers
chriseidhof
4
230
Parsing with Blocks
chriseidhof
2
270
Other Decks in Programming
See All in Programming
Performance Optimization With LLMs
xleitix
0
250
作れるエンジニアから、価値を届けるエンジニアへ
ryunakayama
1
250
Spec-driven Development with AI
simas
PRO
0
2.3k
AIがコードを書いてくれる時代、我々は何を確かめるのか
yosuke_furukawa
PRO
13
5.8k
TS 7.0 で baseUrl が使えなくなった今、パスエイリアスをどうするか
bicstone
2
580
Enforcing Your Architecture with Unit Tests in the AI Era (Swift Connection X)
steliosf
PRO
1
150
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1.9k
graphql-ruby を Spinel で速くしようとした話
mtsmfm
0
140
AmebaブログはKMPから卒業します
kmars0605
0
340
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
2.3k
Railsバージョンを4倍にした話
optim
0
970
[DroidKnights 2026] Workflow AX: From Auto-Documented Policies to E2E Testing
raeminkang
0
540
Featured
See All Featured
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
560
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.7k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
530
Being A Developer After 40
akosma
PRO
92
590k
Ethics towards AI in product and experience design
skipperchong
2
460
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
670
Facilitating Awesome Meetings
lara
57
7.2k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.7k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.5k
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?