Skip to content

Instantly share code, notes, and snippets.

@djburdick
Last active December 24, 2015 08:59
Show Gist options
  • Save djburdick/6773784 to your computer and use it in GitHub Desktop.
Save djburdick/6773784 to your computer and use it in GitHub Desktop.
objective-c cheatsheet. #objc
// == Basics ==
// objective-c is the same as C (just a superset of C)
// [, @, NS are the objective-c clues (things not allowed in C)
// NS == NextStep operating system
// Mac OSX is built on objective-c
NSLog // print
NSLog(@"There are %i minutes in a %i year", minutesInAYear, numYear);
%i // integer place holder
%f // float/double. writes out 6 places
%e // exponential. or proper floating/double point notation
%c // char
%i // bool. 0 == NO; 1 == YES
%@ // write out objects (strings etc)
%lu // unsigned long int
// Prefix and postfix incrementing:
++a;
a++;
// Ternary operator:
int highScore = playerOne > playerTwo ? playerOne : playerTwo;
// == FUNCTIONS ==
int sum (int x, int y) {
return x + y;
}
// Need prototype if function is below caller
// == Variables ==
// camel case convention
int myVar = 1;
// all the normal c data types (int, char, short, long, float, double etc)
BOOL // obj-c only
unsigned int myInt;
long int myBigInt; // if you compile in 32 bit this will only take up 4-bytes (not 8). should avoid long int since it's not cross platform
long long int myBigInt; // this will take up 8 bytes on 32 bit and also 8 on 64 bit
short int myShort; // 2 bytes
float myFloat = 7.2f; // f is optional. 4 bytes
double myFloat = 7.2; // 8 bytes
int a = 25;
int b = 2;
float result = a / b; // this will turncate the .5. must cast first
float result = (float) a / b; // this will turncate the .5. must cast first
// currency shouldn't use floats. need to use decimal arthimetic
char // 1 byte (in ascii set)
BOOL isCompleted = YES;
BOOL isCompleted = NO;
bool myBool = true; // this is valid c. it's only in newer c.
Strings:
@"Hello"; // strings need @ sign since C doesn't have strings as a basic type
NSString *myString = @"Hello"; // NSString is imported through foundation
// @ sign is a clue to the compiler that this isn't a C style char array
// * is a pointer
//
NSString * myString;
myString = @"Hello";
NSMutableString; // if you want to append to a string
[myString writeToURL:fileURL]; // NSString and other obj-c classes can write their own data out
// == Enumerators ==
// stored internally as an int
enum seatPreference { window, aisle, middle };
enum seatPreference bobSeat = window;
// define your own types
typedef enum { window, aisle, middle } seatPreference
seatPreference bobSeat = window;
// == Preprocessor directives ==
// same as in C
#import
#define HIGHSCORE 1000000
#if DEBUG
// compiler will ingore code in here unless compiled as debug
#endif
// == Classes ==
// all objects are accessed using pointers
NSClass *myClass = [[NSClass alloc] init];
NSDate *today = [NSDate date]; // calling date class method which instantiates the object.
NSString* myString = [NSString string]; // autoreleased object
NSString* myString = [[NSString alloc] init]; // manual style
// alloc allocates the memory
// init initializes the class (calls constructor etc)
// passing object
void function (NSString *myString) {
}
// method calling syntax. ruby, java vs objc
result = myObject.method(param); // ruby, java etc
result = [myObject method:param]; // objc
result = myObject.method("/tmp/log.txt", YES); // ruby, java
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
BOOL result = [myData writeToFile:@"/tmp/log.txt" atomically:NO];
writeToFile:atomically: is the method name
myObject.method(getValue()); // ruby, java
[myObject method:[anotherObject getValue]];
upper = message.toUpper();
NSString *message2 = [message uppercaseString];
id myObject = [NSString string]; // id can be any type of object (similar to void in C). id is a pointer
[myDate date]; // instance (- sign)
[NSDate date]; // class (+ sign)
// everything inherits from NSObject
// overriding is legal. just use the same name and params.
// don't need to list overridden methods in header file
@implementation MyClass
-(id)init
{
self = [super init];
}
@end
interface (header) file
- says what's available
implementation (.m) file
- how
#import <Foundation/Foundation.h>
@interface Character : NSObject {
// instance vars here
// the curly braces are optional as @property automatically defines an instances variable for you
}
@property NSString *name;
@property int hitPoints;
@property NSDate *creationDate;
-(void) someMethod;
@end
#import "Character.h"
@implementation Character
@synthesize name, creationDate, hitPoints;
-(void) someMethod {
NSLog(@"I'm a method");
}
@end
#import <Foundation/Foundation.h>
#import "Character.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Character *myCharacter = [[Character alloc] init];
[myCharacter someMethod];
}
return 0;
}
// == Methods ==
- (void) someMethod; // - means instance
+ (void) someMethod; // + means class
- (int) timesTen : (int) param;
- (NSString *) createMessage: (NSString *) input;
- (int) addNumber: (int) a toNumber: (int) b;
// == Accessors ==
instance variables are private (like ruby)
attr_accessor :caption
[photo setCaption:@"Day at the Beach"]; // setter
output = [photo caption]; // getter
// == Memory Management ==
// obj-c does have a garbage collector but can't be used on iphone, ipad
[myObj release];
myObj // dangling pointer
myObj = nil; // optional to clear pointer address
[myObj autorelease]; // autorelease means release it later
// when calling "autorelease" it adds object to a pool. then the pool is drained repeatedly at the end of every event loop
ex:
createEmployee {
Employee *fred = [[Employee alloc] init];
[fred autorelease];
return fred;
}
// memory leak:
// when you don't release memory
// if you own the object you must release it
// alloc
// new
// copy
// retain
// must be balanced w/ a
// release
// if you don't own the object you must NOT release it. if you didn't use NARC then you don't own that object
NSDate *date = [NSDate new];
// new does both alloc and init
NSDate *date = [NSDate alloc];
date = [date init];
NSDate *date = [[NSDate alloc] init]; // most common way to instantiate an object
date retainCount: 1
do this instead of "new" b/c of different initailzer methods
NSDate *myDate = [NSDate date]; // you don't need to call release on this b/c it's up to the method implementer to call autorelease within that method
// == ARC ==
- you don't write release and retain calls anymore
- the compiler writes the retain and release calls
- on for new projects by default
- ARC doesn't allow memory management code
- should be using it in every new obj-c project
- is not garbage collection (it's done at compile time)
- deals with objects only
- rules of ARC: don't call memory management methods, no retainCount, can't call dealloc, don't use NSAutoReleasePool, no object references in C structs
- don't need to release instance vars with dealloc. so don't need to include dealloc
- dealloc // is a destructor. should be kept as simple as possible. don't put normal logic in these. eg: db disconnect code
// == Properties ==
- used to not have properties. just instance vars (ie: regular vars defined in the header file)
- style habit is to name instance vars with a leading underscore _ivar
- generally put in .m unless required for public interface
// in .h or .m
@property int score; // replaces ivar
// in .m
@sythesize score; // replaces getter and setter methods. not needed in xcode 4.4+
@property (strong) NSString *name; // ARC will keep this reference around
@property (readonly) int employeeID; // no setter method created
@property (nonatomic, strong) IBOutlet UITextField *fahrenheit; // IBOutlet for iOS connection
parameters:
- nonatomic // not thread safe. lower footprint. generally want to use this unless specific need for threading.
- automic // threadsafe
- assign // all primitive types (int etc, NSString *name)
- strong // for objects
- weak // for delegate objects (id delegate) and IBOutlet // autozeros references when object goes away
- copy // deep object copy
- readonly // only getter method
// put instance variables in the .m file if they are private to the class
@implementation Player
{
int privateValue; // instance var
}
@end
// == Initializers ==
- all classes have "init" method this b/c of NSObject
- are just regular methods. by convention they should start with "init"
- (id)init
{
self = [super init];
if (self) {
score = 5000;
}
return self;
}
if you create custom init methods you need to define them in the header
- make sure multiple inits are DRY. have the one with the most params do the work
// == Arrays ==
- C style arrays
- no bounds checking
- fixed size
- can't mix types
int intArr[5];
intArr[0] = 50;
intArr[1] = 60;
// or
int intArr[5] = {50, 60, 70, 80, 90};
// or
int intArr[] = {50, 60, 70, 80, 90};
NSString *myStringArray[5]; // holds 5 pointers to NSString objects
myStringArray[0] = [[NSString alloc] initWithString:@"Hello"];
myStringArray[0] = @"Hello";
NSArray *myArray = [[NSArray alloc] initWithObjects:@"one",@"two",nil]; // nil needs to be the last element
NSArray *myArray = [NSArray arrayWithObjects:@"one",@"two",nil]; // autoreleased array
NSString *elem = [myArray objectAtIndex:1];
- can hold different types of objects in the same array
- NSArray is immutable (can't add or remove objects from it after created)
NSArray *blah = @[@"a",@"b"]; // create an array on the fly
NSMutableArray
[myArray addObject:@"three"]
- can add or remove objects
// == Dictionary (hash) ==
NSDictionary *states = [NSDictionary dictionaryWithObjectsAndKeys:
@"Arizona",@"AZ",
@"California", @"CA",
nil];
NSString *someState = @"CA";
NSLog(@"key stands for %@", [states objectForKey:someState]);
// it's immutable
NSMutableDictionary
// is mutable
[states setObjectForKey:@"Florida" forKey:@"FL"];
// == Enumeration ==
for (NSString *key in states) {
NSLog(@"key stands for %@", [states objectForKey:key]);
}
for (element in collection) {
}
// == Files ==
NSFileManager *fileMgr = [[NSFileManager alloc] init];
- move, exist, remove etc
if ([fileMgr fileExistsAtPath:path] {
}
// == Categories ==
- these let you add methods to an existing class (so you don't need to extend classes as often creating your own custom string class etc)
- like ruby monkeypatching
@interface NSString (category)
// no new instance variables
// add methods
@end
// name of category convention "NSString_ConvertWhiteSpace"
// will need to #import category header file
// == Protocols ==
- like an interface in java
- list of methods you want an object to perform
- you must implement these methods
- allows you to pass your object into other methods b/c the receiving class knows you have the required methods
@protocol Cleaner
@required
- (void) vacuum;
@optional
- (void) cleanWindows;
@end
conforming to a protocol
@interface MyClass : NSObject <Cleaner>
// == Dynamic Typing ==
- id return type can represent any object
- only use dynamic typing if necessary
id whoKnows = [[MyClass alloc] init];
// using id since myArray contains different objects
for (id obj in myArray) {
if ([obj isKindOfClass:[Blah class]]) {
//
}
}
// == Debugging ==
- start at first issue and work your way down (in xcode issue navigator)
- "undeclared identified" == i don't know what this is. check to make sure its header is imported (eg: #import "myClass.h")
- double quotes vs single quotes matter. only chars use single quotes
- don't ignore xcode warnings. there are many that will make your program crash
- you can send message to a null pointer (b/c of dynamic typing)
// == Exceptions ==
- only catch exceptions when really necessary
@try {
} @catch (NSException *ex) {
// do something
} @finally {
// executed regardless of exception or not
// could close a DB connection or something like that
}
// == Misc ==
URLs:
NSURL vs a regular string
- apple wants you to use this
- faster than just strings
- catches errors
- built in methods for managing etc
NSString *path = @"/Users/dj/file.txt";
NSURL *myURL = [NSURL fileURLWithPath:path]; // autoreleased
NSKeyedArchiver
- like a flat file database (or xml file)
- use encodeWithCoder method to tell archiver how it's keyed and what's stored
- saved as .plist file by default
- initWithCoder to tell program how to read from archive
NSKeyedUnarchiver
// == Constants ==
- in .m file
static const float DefaultFahrenheit = 80.0;
// static - available to the current file only
// const - means throw error if this variable is changed later in the program
// extern - available to other files. used instead of static in the .h file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment