Objective C Notes For Professionals
Objective C Notes For Professionals
Objective-C
Notes for Professionals
®
100+ pages
of professional hints and tricks
Disclaimer
GoalKicker.com This is an unocial free book created for educational purposes and is
not aliated with ocial Objective-C® group(s) or company(s).
Free Programming Books All trademarks and registered trademarks are
the property of their respective owners
Contents
About ................................................................................................................................................................................... 1
Chapter 1: Getting started with Objective-C Language ............................................................................ 2
Section 1.1: Hello World ................................................................................................................................................. 2
Chapter 2: Basic Data Types .................................................................................................................................. 4
Section 2.1: SEL ............................................................................................................................................................... 4
Section 2.2: BOOL .......................................................................................................................................................... 4
Section 2.3: id ................................................................................................................................................................. 5
Section 2.4: IMP (implementation pointer) ................................................................................................................. 5
Section 2.5: NSInteger and NSUInteger ...................................................................................................................... 6
Chapter 3: Enums .......................................................................................................................................................... 8
Section 3.1: typedef enum declaration in Objective-C ............................................................................................... 8
Section 3.2: Converting C++ std::vector<Enum> to an Objective-C Array ............................................................... 8
Section 3.3: Defining an enum ...................................................................................................................................... 9
Chapter 4: Structs ...................................................................................................................................................... 10
Section 4.1: Defining a Structure and Accessing Structure Members .................................................................... 10
Section 4.2: CGPoint .................................................................................................................................................... 10
Chapter 5: Classes and Objects .......................................................................................................................... 12
Section 5.1: Dierence between allocation and initialization .................................................................................. 12
Section 5.2: Creating classes with initialization values ............................................................................................ 12
Section 5.3: Specifying Generics ................................................................................................................................ 13
Section 5.4: Singleton Class ........................................................................................................................................ 13
Section 5.5: The "instancetype" return type ............................................................................................................. 14
Chapter 6: Inheritance ............................................................................................................................................. 15
Section 6.1: Car is inherited from Vehicle .................................................................................................................. 15
Chapter 7: Methods ................................................................................................................................................... 17
Section 7.1: Class methods .......................................................................................................................................... 17
Section 7.2: Pass by value parameter passing ........................................................................................................ 17
Section 7.3: Pass by reference parameter passing ................................................................................................. 17
Section 7.4: Method parameters ................................................................................................................................ 18
Section 7.5: Create a basic method ........................................................................................................................... 18
Section 7.6: Return values .......................................................................................................................................... 19
Section 7.7: Calling methods ...................................................................................................................................... 19
Section 7.8: Instance methods ................................................................................................................................... 20
Chapter 8: Properties ............................................................................................................................................... 21
Section 8.1: Custom getters and setters .................................................................................................................... 21
Section 8.2: Properties that cause updates .............................................................................................................. 22
Section 8.3: What are properties? ............................................................................................................................. 23
Chapter 9: Random Integer .................................................................................................................................. 26
Section 9.1: Basic Random Integer ............................................................................................................................ 26
Section 9.2: Random Integer within a Range ........................................................................................................... 26
Chapter 10: BOOL / bool / Boolean / NSCFBoolean ................................................................................ 27
Section 10.1: BOOL/Boolean/bool/NSCFBoolean .................................................................................................... 27
Section 10.2: BOOL VS Boolean ................................................................................................................................. 27
Chapter 11: Continue and Break! ......................................................................................................................... 28
Section 11.1: Continue and Break Statement ............................................................................................................. 28
Chapter 12: Key Value Coding / Key Value Observing ............................................................................ 29
Section 12.1: Most Common Real Life Key Value Coding Example ........................................................................ 29
Section 12.2: Querying KVC Data .............................................................................................................................. 29
Section 12.3: Collection Operators ............................................................................................................................. 30
Section 12.4: Key Value Observing ............................................................................................................................ 32
Chapter 13: NSString ................................................................................................................................................. 35
Section 13.1: Encoding and Decoding ........................................................................................................................ 35
Section 13.2: String Length .......................................................................................................................................... 35
Section 13.3: Comparing Strings ................................................................................................................................. 35
Section 13.4: Splitting ................................................................................................................................................... 36
Section 13.5: Searching for a Substring ..................................................................................................................... 37
Section 13.6: Creation .................................................................................................................................................. 37
Section 13.7: Changing Case ....................................................................................................................................... 38
Section 13.8: Removing Leading and Trailing Whitespace ..................................................................................... 38
Section 13.9: Joining an Array of Strings .................................................................................................................. 38
Section 13.10: Formatting ............................................................................................................................................ 39
Section 13.11: Working with C Strings ......................................................................................................................... 39
Section 13.12: Reversing a NSString Objective-C ...................................................................................................... 39
Chapter 14: NSArray ................................................................................................................................................. 41
Section 14.1: Creating Arrays ...................................................................................................................................... 41
Section 14.2: Accessing elements ............................................................................................................................... 41
Section 14.3: Using Generics ....................................................................................................................................... 41
Section 14.4: Reverse an Array .................................................................................................................................. 42
Section 14.5: Converting between Sets and Arrays ................................................................................................. 42
Section 14.6: Converting NSArray to NSMutableArray to allow modification ....................................................... 42
Section 14.7: Looping through .................................................................................................................................... 42
Section 14.8: Enumerating using blocks .................................................................................................................... 43
Section 14.9: Comparing arrays ................................................................................................................................. 43
Section 14.10: Filtering Arrays With Predicates ......................................................................................................... 43
Section 14.11: Sorting array with custom objects ...................................................................................................... 44
Section 14.12: Sorting Arrays ...................................................................................................................................... 44
Section 14.13: Filter NSArray and NSMutableArray .................................................................................................. 45
Section 14.14: Add objects to NSArray ....................................................................................................................... 45
Section 14.15: Finding out the Number of Elements in an Array ............................................................................. 45
Section 14.16: Creating NSArray instances ................................................................................................................ 45
Chapter 15: NSMutableArray ................................................................................................................................ 46
Section 15.1: Sorting Arrays ......................................................................................................................................... 46
Section 15.2: Creating an NSMutableArray ............................................................................................................... 46
Section 15.3: Adding elements .................................................................................................................................... 46
Section 15.4: Insert Elements ...................................................................................................................................... 46
Section 15.5: Deleting Elements .................................................................................................................................. 46
Section 15.6: Move object to another index .............................................................................................................. 47
Section 15.7: Filtering Array content with Predicate ................................................................................................ 47
Chapter 16: NSDictionary ........................................................................................................................................ 48
Section 16.1: Create ...................................................................................................................................................... 48
Section 16.2: Fast Enumeration .................................................................................................................................. 48
Section 16.3: Creating using literals ........................................................................................................................... 48
Section 16.4: Creating using dictionaryWithObjectsAndKeys: ................................................................................ 48
Section 16.5: NSDictionary to NSArray ...................................................................................................................... 49
Section 16.6: NSDictionary to NSData ....................................................................................................................... 49
Section 16.7: NSDictionary to JSON ........................................................................................................................... 49
Section 16.8: Creating using plists .............................................................................................................................. 49
Section 16.9: Setting a Value in NSDictionary ........................................................................................................... 49
Section 16.10: Getting a Value from NSDictionary ................................................................................................... 50
Section 16.11: Check if NSDictionary already has a key or not ............................................................................... 50
Section 16.12: Block Based Enumeration ................................................................................................................... 50
Chapter 17: NSMutableDictionary ...................................................................................................................... 52
Section 17.1: NSMutableDictionary Example ............................................................................................................. 52
Section 17.2: Removing Entries From a Mutable Dictionary ................................................................................... 53
Chapter 18: NSDate .................................................................................................................................................... 55
Section 18.1: Convert NSDate that is composed from hour and minute (only) to a full NSDate ........................ 55
Section 18.2: Converting NSDate to NSString ........................................................................................................... 55
Section 18.3: Creating an NSDate .............................................................................................................................. 56
Section 18.4: Date Comparison .................................................................................................................................. 56
Chapter 19: NSURL ..................................................................................................................................................... 58
Section 19.1: Create ...................................................................................................................................................... 58
Section 19.2: Compare NSURL ................................................................................................................................... 58
Section 19.3: Modifying and Converting a File URL with removing and appending path .................................... 58
Chapter 20: NSUrl send a post request .......................................................................................................... 60
Section 20.1: Simple POST request ............................................................................................................................ 60
Section 20.2: Simple Post Request With Timeout .................................................................................................... 60
Chapter 21: NSData .................................................................................................................................................... 61
Section 21.1: Create ...................................................................................................................................................... 61
Section 21.2: NSData and Hexadecimal String ......................................................................................................... 61
Section 21.3: Get NSData length ................................................................................................................................ 62
Section 21.4: Encoding and decoding a string using NSData Base64 ................................................................... 62
Chapter 22: NSPredicate ......................................................................................................................................... 63
Section 22.1: Filter By Name ....................................................................................................................................... 63
Section 22.2: Find movies except given ids .............................................................................................................. 64
Section 22.3: Find all the objects which is of type movie ........................................................................................ 64
Section 22.4: Find Distinct object ids of array .......................................................................................................... 64
Section 22.5: Find movies with specific ids ............................................................................................................... 64
Section 22.6: Case Insensitive comparison with exact title match ......................................................................... 64
Section 22.7: Case sensitive with exact title match .................................................................................................. 64
Section 22.8: Case Insensitive comparison with matching subset ......................................................................... 65
Chapter 23: NSRegularExpression ..................................................................................................................... 66
Section 23.1: Check whether a string matches a pattern ........................................................................................ 66
Section 23.2: Find all the numbers in a string .......................................................................................................... 66
Chapter 24: NSJSONSerialization ...................................................................................................................... 67
Section 24.1: JSON Parsing using NSJSONSerialization Objective-C ..................................................................... 67
Chapter 25: NSCalendar .......................................................................................................................................... 69
Section 25.1: System Locale Information .................................................................................................................. 69
Section 25.2: Initializing a Calendar ........................................................................................................................... 69
Section 25.3: Calendrical Calculations ...................................................................................................................... 69
Chapter 26: NSAttributedString .......................................................................................................................... 71
Section 26.1: Using Enumerating over Attributes in a String and underline part of string .................................. 71
Section 26.2: Creating a string that has custom kerning (letter spacing) editshare ........................................... 71
Section 26.3: Create a string with text struck through ............................................................................................ 71
Section 26.4: How you create a tri-color attributed string ..................................................................................... 72
Chapter 27: NSTimer ................................................................................................................................................. 73
Section 27.1: Storing information in the Timer .......................................................................................................... 73
Section 27.2: Creating a Timer ................................................................................................................................... 73
Section 27.3: Invalidating a timer ............................................................................................................................... 73
Section 27.4: Manually firing a timer ......................................................................................................................... 74
Chapter 28: NSObject ............................................................................................................................................... 75
Section 28.1: NSObject ................................................................................................................................................ 75
Chapter 29: NSSortDescriptor ............................................................................................................................. 76
Section 29.1: Sorted by combinations of NSSortDescriptor .................................................................................... 76
Chapter 30: NSTextAttachment .......................................................................................................................... 77
Section 30.1: NSTextAttachment Example ................................................................................................................ 77
Chapter 31: NSCache ................................................................................................................................................. 78
Section 31.1: NSCache .................................................................................................................................................. 78
Chapter 32: NSUserDefaults ................................................................................................................................. 79
Section 32.1: Simple example ..................................................................................................................................... 79
Section 32.2: Clear NSUserDefaults .......................................................................................................................... 79
Chapter 33: Subscripting ......................................................................................................................................... 80
Section 33.1: Subscripts with NSArray ....................................................................................................................... 80
Section 33.2: Custom Subscripting ............................................................................................................................ 80
Section 33.3: Subscripts with NSDictionary ............................................................................................................... 80
Chapter 34: Low-level Runtime Environment .............................................................................................. 82
Section 34.1: Augmenting methods using Method Swizzling .................................................................................. 82
Section 34.2: Attach object to another existing object (association) .................................................................... 83
Section 34.3: Calling methods directly ...................................................................................................................... 83
Chapter 35: Fast Enumeration ............................................................................................................................. 85
Section 35.1: Fast enumeration of an NSArray with index ...................................................................................... 85
Section 35.2: Fast enumeration of an NSArray ........................................................................................................ 85
Chapter 36: Categories ............................................................................................................................................ 86
Section 36.1: Conforming to protocol ........................................................................................................................ 86
Section 36.2: Simple Category ................................................................................................................................... 86
Section 36.3: Declaring a class method .................................................................................................................... 86
Section 36.4: Adding a property with a category .................................................................................................... 87
Section 36.5: Create a Category on XCode .............................................................................................................. 87
Chapter 37: Protocols ............................................................................................................................................... 91
Section 37.1: Optional and required methods ........................................................................................................... 91
Section 37.2: Checking existence of optional method implementations ............................................................... 91
Section 37.3: Forward Declarations ........................................................................................................................... 91
Section 37.4: Conforming to Protocols ...................................................................................................................... 92
Section 37.5: Basic Protocol Definition ...................................................................................................................... 92
Section 37.6: Check conforms Protocol .................................................................................................................... 92
Chapter 38: Protocols and Delegates .............................................................................................................. 93
Section 38.1: Implementation of Protocols and Delegation mechanism ............................................................... 93
Chapter 39: Blocks ...................................................................................................................................................... 94
Section 39.1: Block Typedefs ...................................................................................................................................... 94
Section 39.2: Blocks as Properties ............................................................................................................................. 94
Section 39.3: Blocks as local variables ...................................................................................................................... 95
Section 39.4: Blocks as Method Parameters ............................................................................................................ 95
Section 39.5: Defining and Assigning ........................................................................................................................ 95
Chapter 40: XML parsing ........................................................................................................................................ 96
Section 40.1: XML Parsing ........................................................................................................................................... 96
Chapter 41: Declare class method and instance method ...................................................................... 98
Section 41.1: How to declare class method and instance method ......................................................................... 98
Chapter 42: Predefined Macros .......................................................................................................................... 99
Section 42.1: Predefined Macros ................................................................................................................................ 99
Chapter 43: Grand Central Dispatch .............................................................................................................. 100
Section 43.1: What is Grand central dispatch ......................................................................................................... 100
Chapter 44: Format-Specifiers ......................................................................................................................... 101
Section 44.1: Integer Example - %i ........................................................................................................................... 101
Chapter 45: Logging ............................................................................................................................................... 102
Section 45.1: Logging ................................................................................................................................................ 102
Section 45.2: NSLog Output Format ....................................................................................................................... 102
Section 45.3: Removing Log Statements from Release Builds ............................................................................ 102
Section 45.4: Logging Variable Values ................................................................................................................... 102
Section 45.5: Empty message is not printed .......................................................................................................... 103
Section 45.6: Using __FUNCTION __ ..................................................................................................................... 103
Section 45.7: NSLog vs printf ................................................................................................................................... 103
Section 45.8: Logging NSLog meta data ................................................................................................................ 104
Section 45.9: NSLog and BOOL type ....................................................................................................................... 104
Section 45.10: Logging by Appending to a File ...................................................................................................... 105
Chapter 46: Error Handling ................................................................................................................................. 106
Section 46.1: Error & Exception handling with try catch block .............................................................................. 106
Section 46.2: Asserting .............................................................................................................................................. 106
Chapter 47: Modern Objective-C ...................................................................................................................... 108
Section 47.1: Literals .................................................................................................................................................. 108
Section 47.2: Container subscripting ....................................................................................................................... 108
Chapter 48: Singletons .......................................................................................................................................... 110
Section 48.1: Using Grand Central Dispatch (GCD) ................................................................................................ 110
Section 48.2: Creating Singleton and also preventing it from having multiple instance using alloc/init, new
............................................................................................................................................................................. 110
Section 48.3: Creating Singleton class and also preventing it from having multiple instances using
alloc/init ............................................................................................................................................................. 111
Chapter 49: Multi-Threading .............................................................................................................................. 112
Section 49.1: Creating a simple thread .................................................................................................................... 112
Section 49.2: Create more complex thread ............................................................................................................ 112
Section 49.3: Thread-local storage ......................................................................................................................... 113
Chapter 50: Unit testing using Xcode ............................................................................................................ 114
Section 50.1: Note: ..................................................................................................................................................... 114
Section 50.2: Testing a block of code or some method: ....................................................................................... 114
Section 50.3: Testing asynchronous block of code: .............................................................................................. 114
Section 50.4: Measuring Performance of a block of code: ................................................................................... 115
Section 50.5: Running Test Suits: ............................................................................................................................. 115
Chapter 51: Memory Management .................................................................................................................. 116
Section 51.1: Memory management rules when using manual reference counting ........................................... 116
Section 51.2: Automatic Reference Counting ......................................................................................................... 117
Section 51.3: Strong and weak references .............................................................................................................. 118
Section 51.4: Manual Memory Management .......................................................................................................... 118
Credits ............................................................................................................................................................................ 120
You may also like ...................................................................................................................................................... 122
About
Please feel free to share this PDF with anyone for free,
latest version of this book can be downloaded from:
http://GoalKicker.com/ObjectiveCBook
This Objective-C® Notes for Professionals book is compiled from Stack Overflow
Documentation, the content is written by the beautiful people at Stack Overflow.
Text content is released under Creative Commons BY-SA, see credits at the end
of this book whom contributed to the various chapters. Images may be copyright
of their respective owners unless otherwise specified
This is an unofficial free book created for educational purposes and is not
affiliated with official Objective-C® group(s) or company(s) nor Stack Overflow.
All trademarks and registered trademarks are the property of their respective
company owners
#import <Foundation/Foundation.h>
#import is a pre-processor directive, which indicates we want to import or include the information from that file into
the program. In this case, the compiler will copy the contents of Foundation.h in the Foundation framework to the
top of the file. The main difference between #import and #include is that #import is "smart" enough to not
reprocess files that have already been included in other #includes.
The NSLog() function will print the string provided to the console, along with some debugging information. In this
case, we use an Objective-C string literal: @"Hello World!". In C, you would write this as "Hello World!", however,
Apple's Foundation Framework adds the NSString class which provides a lot of useful functionality, and is used by
NSLog. The simplest way to create an instance of NSString is like this: @">string content here".
Technically, NSLog() is part of Apple's Foundation Framework and is not actually part of the Objective-C
language. However, the Foundation Framework is ubiquitous throughout Objective-C programming. Since
the Foundation Framework is not open-source and cannot be used outside of Apple development, there
are open-source alternatives to the framework which are associated with OPENStep and GNUStep.
Assuming we want to compile our Hello World program, which consist of a single hello.m file, the command to
compile the executable is:
./hello
Hello World!
-o: This option indicate to which file we'd like to output our program. In our case hello. If not specified, the
default value is a.out.
In the example below, there are two selectors. new and setName:
Each pair of brackets corresponds to a message send. On the first line we send a message containing the new
selector to the Person class and on the second line we send a message containing the setName: selector and a
string. The receiver of these messages uses the selector to look up the correct action to perform.
Most of the time, message passing using the bracket syntax is sufficient, but occasionally you need to work with the
selector itself. In these cases, the SEL type can be used to hold a reference to the selector.
If the selector is available at compile time, you can use @selector() to get a reference to it.
SEL s = @selector(setName:);
SEL s NSSelectorFromString(@"setName:");
When using NSSelectorFromString, make sure to wrap the selector name in a NSString.
if ([self.myDelegate respondsToSelector:@selector(doSomething)]) {
[self.myDelegate doSomething];
}
A BOOL is a primitive, and so it cannot be stored directly in a Foundation collection. It must be wrapped in an
NSNumber. Clang provides special syntax for this:
The BOOL implementation is directly based on C's, in that it is a typedef of the C99 standard type bool. The YES and
NO values are defined to __objc_yes and __objc_no, respectively. These special values are compiler builtins
introduced by Clang, which are translated to (BOOL)1 and (BOOL)0. If they are not available, YES and NO are defined
directly as the cast-integer form. The definitions are found in the Objective-C runtime header objc.h
Section 2.3: id
id is the generic object pointer, an Objective-C type representing "any object". An instance of any Objective-C class
can be stored in an id variable. An id and any other class type can be assigned back and forth without casting:
id anonymousSurname = @"Doe";
NSString * surname = anonymousSurname;
id anonymousFullName = [NSString stringWithFormat:@"%@, John", surname];
This becomes relevant when retrieving objects from a collection. The return types of methods like objectAtIndex:
are id for exactly this reason.
It also means that a method or function parameter typed as id can accept any object.
When an object is typed as id, any known message can be passed to it: method dispatch does not depend on the
compile-time type.
NSString * extinctBirdMaybe =
[anonymousSurname stringByAppendingString:anonymousSurname];
A message that the object does not actually respond to will still cause an exception at runtime, of course.
NSDate * nope;
if([anonymousSurname isKindOfClass:[NSDate class]]){
nope = [anonymousSurname addTimeInterval:10];
}
Syntax:
Example 1:
The method addressed by the IMP can be called by dereferencing the IMP.
ImpDoSomething(myObject, @selector(doSomething));
myImpDoSomething(myObject, @selector(doSomething));
[myObject doSomething]
[myObject performSelector:mySelector]
[myObject performSelector:@selector(doSomething)]
[myObject performSelector:NSSelectorFromString(@"doSomething")];
Example 2:
Here, we call [NSObject methodForSelector which returns us a pointer to the C function that actually implements
the method, which we can the subsequently call directly.
The difference between an signed and an unsigned int or long is that a signed int or long can contain negative
Most methods Apple provides are returning an NS(U)Integer over the normal int. You'll get a warning if you try to
cast it to a normal int because you will lose precision if you are running on a 64-bit architecture. Not that it would
matter in most cases, but it is easier to use NS(U)Integer. For example, the count method on an array will return an
NSUInteger.
Just like a BOOL, the NS(U)Integer is a primitive datatype, so you sometimes need to wrap it in a NSNumber you can
use the @ before the integer to cast it like above and retrieve it using the methods below. But to cast it to
NSNumber, you could also use the following methods:
[NSNumber numberWithInteger:0];
[NSNumber numberWithUnsignedInteger:0];
typedef enum {
Monday=1,
Tuesday,
Wednesday
} WORKDAYS;
typedef enum
{
Error0 = 0,
Error1 = 1,
Error2 = 2
} MyError;
@end
@implementation ErrorEnumObj
- (MyError) getEnumValue
{
return (MyError)self.intValue;
}
@end
private:
__weak Listener* _listener;
}
If this kind of solution is to be used on multiple enums, the creation of the EnumObj (declaration & implementation)
can be done using a macro (to create a template like solution).
You also can set your own raw-values to the enumeration types.
You can also specify on the first value and all the following will use it with increment:
typedef struct {
float x, y, z;
} ThreeFloats;
@interface MyClass
- (void)setThreeFloats:(ThreeFloats)threeFloats;
- (ThreeFloats)threeFloats;
@end
Sending an instance of MyClass the message valueForKey: with the parameter @"threeFloats" will invoke the
MyClass method threeFloats and return the result wrapped in an NSValue.
typedef struct {
CGFloat x;
CGFloat y;
} CGPoint;
If you used Objective-C for Mac or iOS app development before, you've almost certainly come across CGPoint;
CGPoints hold the position of pretty much everything on screen, from views and controls to objects in a game to
changes in a gradient. This means that CGPoints are used a lot. This is even more true with really performance-
heavy games; these games tend to have a lot of objects, and all of these objects need positions. These positions are
often either CGPoints, or some other type of struct that conveys a point (such as a 3-dimensional point for 3d
games).
@interface CGPoint {
CGFloat x;
CGFloat y;
}
@end
@implementation CGPoint
@synthesize x, y;
...
@end
However, if CGPoint was used in this way it would take a lot longer to create and manipulate points. In smaller,
faster programs this wouldn't really cause a difference, and in those cases it would be OK or maybe even better to
use object points. But in large programs where points are be used a lot, using objects as points can really hurt
performance, making the program slower, and also waste memory, which could force the program to crash.
In Objective-C, these are separate operations. The class methods alloc (and its historic sibling allocWithZone:)
makes the Objective-C runtime reserve the required memory and clears it. Except for a few internal values, all
properties and variables are set to 0/NO/nil.
The object then is already "valid" but we always want to call a method to actually set up the object, which we call an
initializer. These serve the same purpose as constructors in other languages. By convention, these methods start
with init. From a language point of view, they are just normal methods.
// Shorthand:
object = [[MyClass alloc] init];
@end
@implementation Car
@end
The method initWithMotorValue: type andChassisValue: type will be used to initialize the Car objects.
@end
A singleton class returns the same instance no matter how many times an application requests it. Unlike a regular
class, A singleton object provides a global point of access to the resources of its class.
Singletons are used in situations where this single point of control is desirable, such as with classes that offer some
general service or resource.
First, create a New file and subclass it from NSObject. Name it anything, we will use CommonClass here. Xcode will
now generate CommonClass.h and CommonClass.m files for you.
#import <Foundation/Foundation.h>
#import "CommonClass.h"
@implementation CommonClass
+ (CommonClass *)sharedObject {
static CommonClass *sharedClass = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedClass = [[self alloc] init];
});
return sharedClass;
}
- (id)init {
if (self = [super init]) {
self.commonString = @"this is string";
}
@end
The Singleton Class that we created earlier will be accessible from anywhere in the project as long as you have
imported CommonClass.h file in the relevant module. To modify and access the shared data in Singleton Class, you
will have to access the shared Object of that class which can be accessed by using sharedObject method like
following:
[CommonClass sharedObject]
- (instancetype)initWithString:(NSString *)string;
@end
When [[Foo alloc] initWithString:@"abc"] is called, the compiler can infer that the return type is Foo *. The
Bar class derived from Foo but did not override the declaration of the initializer. Yet, thanks to instancetype, the
compiler can infer that [[Bar alloc] initWithString:@"xyz"] returns a value of type Bar *.
Consider the return type of -[Foo initWithString:] being Foo * instead: if you would call [[Bar alloc]
initWithString:], the compiler would infer that a Foo * is returned, not a Bar * as is the intention of the
developer. The instancetype solved this issue.
Before the introduction of instancetype, initializers, static methods like singleton accessors and other methods
that want to return an instance of the receiving class needed to return an id. The problem is that id means "an
object of any type". The compiler is thus not able to detect that NSString *wrong = [[Foo alloc]
initWithString:@"abc"]; is assigning to a variable with an incorrect type.
Due to this issue, initializers should always use instancetype instead of id as the return value.
#import <Foundation/Foundation.h>
{
NSString *vehicleName;
NSInteger vehicleModelNo;
}
@implementation Vehicle
- (void)print{
NSLog(@"Name: %@", vehicleName);
NSLog(@"Model: %ld", vehicleModelNo);
}
@end
{
NSString *carCompanyName;
}
@end
@implementation Car
@end
When the above code is compiled and executed, it produces the following result:
+ (void)hello {
NSLog(@"Hello World");
}
@end
@implementation SwapClass
Output:
@implementation SwapClass
Output:
- (int)addInt:(int)intOne toInt:(int)intTwo {
return intOne + intTwo;
}
The colon (:) separates the parameter from the method name.
- (void)hello {
NSLog(@"Hello World");
}
The (void) denotes the return type. This method doesn't return anything, so you enter void.
- (NSString)returnHello {
return @"Hello World";
}
The value you want to return goes after the return keyword;
[classInstance hello];
@interface Sample
-(void)hello; // exposing the class Instance method
@end
@implementation Sample
-(void)hello{
NSLog(@"hello");
}
@end
[self hello];
@implementation Sample
-(void)otherMethod{
[self hello];
}
-(void)hello{
NSLog(@"hello");
}
@end
@implementation Sample
-(void)add:(NSInteger)add to:(NSInteger)to
NSLog(@"sum = %d",(add+to));
}
@end
[Class hello];
@interface Sample
+(void)hello; // exposing the class method
@end
@end
@implementation MyClass
- (void)someInstanceMethod {
NSLog(@"Whose idea was it to have a method called \"someInstanceMethod\"?");
}
@end
@interface TestClass
@end
@implementation TestClass
- (void)doSomething {
// The next line will call the setSomeString: method
self.someString = @"Test";
}
@end
- (NSString *)someString {
if (_someString == nil) {
_someString = [self getInitialValueForSomeString];
}
return _someString;
}
You can also make a property that computes its value in the getter:
@end
@implementation Circle
- (CGFloat)area {
return M_PI * pow(self.radius, 2);
}
@end
In Shape.h
@interface Shape {
NSUInteger numberOfSides;
CGFloat sideWidth;
UIImage * image;
}
In Shape.m
@implementation AnObject
- (id)initWithNumberOfSides:(NSUInteger)numberOfSides withWidth:(CGFloat)width {
if ((self = [self init])) {
[self setNumberOfSides:numberOfSides andWidth:width];
}
return self;
}
- (void)setNumberOfSides:(NSUInteger)numberOfSides {
_numberOfSides = numberOfSides;
[self updateImage];
}
- (void)setSideWidth:(CGFloat)sideWidth {
_sideWidth = sideWidth;
[self updateImage];
}
- (void)setNumberOfSides:(NSUInteger)numberOfSides andWidth:(CGFloat)sideWidth {
_numberOfSides = numberOfSides;
_sideWidth = sideWidth;
[self updateImage];
}
// Method that does some post-processing once either of the properties has
// been updated.
- (void)updateImage {
...
}
@end
When properties are assigned to (using object.property = value), the setter method setProperty: is called. This
setter, even if provided by @synthesize, can be overridden, as it is in this case for numberOfSides and sideWidth.
However, if you set an property's ivar directly (through property if the object is self, or object->property), it
doesn't call the getter or setter, allowing you to do things like multiple property sets that only call one update or
bypass side-effects caused by the setter.
-(NSString *)someString;
-(void)setSomeString:(NSString *)newString;
-(int)someInt;
-(void)setSomeInt:(NSString *)newInt;
@end
@implementation TestClass
-(NSString *)someString {
return _someString;
}
-(void)setSomeString:(NSString *)newString {
_someString = newString;
}
-(int)someInt {
return _someInt;
}
-(void)setSomeInt:(int)newInt {
_someInt = newInt;
}
@end
This is quite a lot of boilerplate code to create a simple instance variable. You have to create the instance variable &
create accessor methods which do nothing except set or return the instance variable. So with Objective-C 2.0, Apple
introduced properties, which auto-generate some or all of the boilerplate code.
@interface TestClass
@end
@implementation testClass
@end
A property is an instance variable paired with auto-generated getters and setters. For a property called someString,
the getter and setter are called someString and setSomeString: respectively. The name of the instance variable is,
by default, the name of the property prefixed with an underscore (so the instance variable for someString is called
_someString, but this can be overridden with an @synthesize directive in the @implementation section:
[testObject setSomeString:@"Foo"];
NSLog(@"someInt is %d", [testObject someInt]);
testObject.someString = @"Foo";
NSLog(@"someInt is %d", testObject.someInt);
This works to create a range because arc4random_uniform(10) returns an integer between 0 and 9. Adding 3 to
this random integer produces a range between 0 + 3 and 9 + 3.
4. NSCFBoolean is a private class in the NSNumber class cluster. It is a bridge to the CFBooleanRef type, which
is used to wrap boolean values for Core Foundation property lists and collections. CFBoolean defines the
constants kCFBooleanTrue and kCFBooleanFalse. Because CFNumberRef and CFBooleanRef are different
types in Core Foundation, it makes sense that they are represented by different bridging classes in
NSNumber.
Boolean
For the for loop, continue statement causes the conditional test and increment portions of the loop to execute. For
the while and do...while loops, continue statement causes the program control pass to the conditional tests.
#import <Foundation/Foundation.h>
int main ()
{
/* local variable definition */
int a = 10;
/* do loop execution */
do
{
if( a == 15)
{
/* skip the iteration */
a = a + 1;
continue;
}
NSLog(@"value of a: %d\n", a);
a++;
}while( a < 20 );
return 0;
}
Output:
It means that any id object is capable of calling valueForKey method and its various variants like valueForKeyPath
etc. '
It also means that any id object can invoke setValue method and its various variants too.
Example:
Exceptions:
Above example assumes that MyClass has an NSNumber Property called myNumber. If myNumber does not
appear in MyClass interface definition, an NSUndefinedKeyException can be raised at possibly both lines 2 and 5 -
popularly known as:
this class is not key value coding-compliant for the key myNumber.
You can write code that can access properties of a class dynamically, without needing interface for that class. This
means that a table view can display values from any properties of an NSObject derived object, provided its property
names are supplied dynamically at runtime.
In the example above, the code can as well work without MyClass being available and id type obj being available to
calling code.
You can query values stored using KVC quickly and easily, without needing to retrieve or cast these as local
variables.
While this is completely redundant here (we could have just accessed the count property), it can be useful on
occasion, though it is rarely necessary. There are, however, some collection operators that are much more useful,
namely @max, @min, @sum, @avg and the @unionOf family. It is important to note that these operators also require a
separate key path following the operator to function correctly. Here's a list of them and the type of data they work
with:
@max and @min will return the highest or lowest value, respectively, of a property of objects in the collection. For
example, look at the following code:
@property NSInteger x, y;
+ (instancetype)pointWithX:(NSInteger)x y:(NSInteger)y;
@end
...
In just a 4 lines of code and pure Foundation, with the power of Key-Value Coding collection operators we were able
to extract a rectangle that encapsulates all of the points in our array.
It is important to note that these comparisons are made by invoking the compare: method on the objects, so if you
ever want to make your own class compatible with these operators, you must implement this method.
@sum will, as you can probably guess, add up all the values of a property.
+ (instancetype)expenseWithPrice:(NSNumber *)price;
@end
...
Here, we used @sum to find the total price of all the expenses in the array. If we instead wanted to find the average
price we're paying for each expense, we can use @avg:
Finally, there's the @unionOf family. There are five different operators in this family, but they all work mostly the
same, with only small differences between each. First, there's @unionOfObjects which will return an array of the
properties of objects in an array:
And finally, the last 3 operators in the @unionOf family will go one step deeper and return an array of values found
for a property contained inside dually-nested arrays:
NSArray<NSArray<Expense*,Expense*>*> *arrayOfArrays =
@[
@[ [Expense expenseWithPrice:@3.75],
[Expense expenseWithPrice:@14.95]
]
];
// @unionOfArrays
NSArray<NSNumber*> allPrices = [arrayOfArrays valueForKeyPath:
@"@unionOfArrays.price"];
// Equal to @[ @19.99, @14.95, @4.50, @19.99, @3.75, @14.95 ];
// @distinctUnionOfArrays
NSArray<NSNumber*> allPrices = [arrayOfArrays valueForKeyPath:
@"@distinctUnionOfArrays.price"];
// Equal to @[ @19.99, @14.95, @4.50, @3.75 ];
The one missing from this example is @distinctUnionOfSets, however this functions exactly the same as
@distinctUnionOfArrays, but works with and returns NSSets instead (there is no non-distinct version because in
a set, every object must be distinct anyway).
And that's it! Collection operators can be really powerful if used correctly, and can help to avoid having to loop
through stuff unnecessarily.
One last note: you can also use the standard collection operators on arrays of NSNumbers (without additional
property access). To do this, you access the self pseudo-property that just returns the object:
In this case, we want to observe the contentOffset on an object that our observer owns
//
// Class to observe
//
@interface XYZScrollView: NSObject
@property (nonatomic, assign) CGPoint contentOffset;
@end
@implementation XYZScrollView
@end
//
// Class that will observe changes
//
@interface XYZObserver: NSObject
@implementation XYZObserver
// NSKeyValueObservingOptions
//
// - NSKeyValueObservingOptionNew
// - NSKeyValueObservingOptionOld
// - NSKeyValueObservingOptionInitial
// - NSKeyValueObservingOptionPrior
//
// can be combined:
// (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
// handle point
}
} else {
@end
// encode
NSData *utf8Data = [string dataUsingEncoding:NSUTF8StringEncoding];
NSASCIIStringEncoding
NSUTF8StringEncoding
NSUTF16StringEncoding (== NSUnicodeStringEncoding)
Note that utf8Data.bytes does not include a terminating null character, which is necessary for C strings. If you
need a C string, use UTF8String:
As in the Splitting Example, keep in mind that NSString uses UTF-16 to represent characters. The length is actually
just the number of UTF-16 code units. This can differ from what the user perceives as characters.
In order to get the number of user-perceived characters, known technically as "grapheme clusters", you must
iterate over the string with -enumerateSubstringsInRange:options:usingBlock: and keep a count. This is
demonstrated in an answer by Nikolai Ruhe on Stack Overflow.
The == operator just tests for object identity and does not compare the logical values of objects, so it can't be used:
The expression (stringOne == stringTwo) tests to see if the memory addresses of the two strings are the same,
which is usually not what we want.
If the string variables can be nil you have to take care about this case as well:
This condition returns YES when strings have equal values or both are nil.
If you need to break a string into its individual characters, loop over the length of the string and convert each
character into a new string.
As in the Length Example, keep in mind that a "character" here is a UTF-16 code unit, not necessarily what the user
sees as a character. If you use this loop with @" ", you'll see that it's split into four pieces.
This preserves grapheme clusters like the Italian flag as a single substring.
From NSData:
When initializing from NSData, an explicit encoding must be provided as NSString is not able to guess how
characters are represented in the raw data stream. The most common encoding nowadays is UTF-8, which is even a
Avoid using +[NSString stringWithUTF8String:] since it expects an explicitly NULL-terminated C-string, which -
[NSData bytes] does not provide.
From NSArray:
To capitalize the first letter character of each word in a string, use capitalizedString:
Method stringByTrimmingCharactersInSet returns a new string made by removing from both ends of the String
characters contained in a given character set.
For a complete list of Format Specifiers, please see: Objective-C, Format Specifiers, Syntax
You could also use -[NSString cStringUsingEncoding:] if your string is encoded with something other than
UTF-8.
Once you have the const char *, you can work with it similarly to an array of chars:
printf("%c\n", cString[5]);
The objectAtIndex: method provides a single object. The first object in an NSArray is index 0. Since an NSArray can
be homogenous (holding different types of objects), the return type is id ("any object"). (An id can be assigned to a
variable of any other object type.) Importantly, NSArrays can only contain objects. They cannot contain values like
int.
NSUInteger idx = 2;
NSString *color = [myColors objectAtIndex:idx];
// color now points to the string @"Green"
Clang provides a better subscript syntax as part of its array literals functionality:
Both of these throw an exception if the passed index is less than 0 or greater than count - 1.
The firstObject and lastObject are computed properties and return nil rather than crashing for empty arrays.
For single element arrays they return the same object. Although, the firstObject method was not introduced to
NSArray until iOS 4.0.
// Fast enumeration
// myColors cannot be modified inside the loop
for (NSString *color in myColors) {
NSLog(@"Element %@", color);
}
// Using indices
for (NSUInteger i = 0; i < myColors.count; i++) {
NSLog(@"Element %d = %@", i, myColors[i]);
}
// To abort use:
*stop = YES
}];
By setting the stop parameter to YES you can indicate that further enumeration is not needed. to do this simply set
&stop = YES.
NSEnumerationOptions
You can enumerate the array in reverse and / or concurrently :
if ([germanMakes isEqualToArray:sameGermanMakes]) {
NSLog(@"Oh good, literal arrays are the same as NSArrays");
}
The important thing is every pair must pass the isEqual: test. For custom objects this method should be
implemented. It exists in the NSObject protocol.
NSPredicate:
- (NSComparisonResult)compare:(Person *)otherObject {
return [self.birthDate compare:otherObject.birthDate];
}
NSSortDescriptor
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];
You can easily sort by multiple keys by adding more than one to the array. Using custom comparator-methods is
possible as well. Have a look at the documentation.
Blocks
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSDate *first = [(Person*)a birthDate];
NSDate *second = [(Person*)b birthDate];
return [first compare:second];
}];
Performance
The -compare: and block-based methods will be quite a bit faster, in general, than using NSSortDescriptor as the
latter relies on KVC. The primary advantage of the NSSortDescriptor method is that it provides a way to define
your sort order using data, rather than code, which makes it easy to e.g. set things up so users can sort an
NSTableView by clicking on the header row.
Example:
NSLog(@"%@", sortedArray);
NSPredicate *bPredicate =
[NSPredicate predicateWithFormat:@"SELF beginswith[c] 'c'"];
NSArray *beginWithB =
[array filteredArrayUsingPredicate:bPredicate];
// beginWith "C" contains { @"Chris", @"Charlie" }.
NSPredicate *sPredicate =
[NSPredicate predicateWithFormat:@"SELF contains[c] 'a'"];
[array filterUsingPredicate:sPredicate];
// array now contains { @"Charlie", @"Melissa" }
These methods are optimized to recreate the new array very efficiently, usually without having to destroy the
original array or even allocate more memory.
[myColors removeAllObjects];
[myColors removeLastObject];
NSUInteger fromIndex = 2;
NSUInteger toIndex = 0;
Example:
or
NSDictionary stockSymbolsDictionary = @{
@"AAPL": @"Apple",
@"GOOGL": @"Alphabet",
@"MSFT": @"Microsoft",
@"AMZN": @"Amazon"
};
Because NSDictionary is inherently unordered, the order of keys that in the for loop is not guaranteed.
It's important to remember that when instantiating dictionaries this way the values go first and the keys second. In
the example above the strings are the keys and the numbers are the values. The method's name reflects this too:
dictionaryWithObjectsAndKeys. While this is not incorrect, the more modern way of instantiating dictionaries (with
literals) is preferred.
Get keys:
Get values:
Reserve path:
Standard
Just like any other object, call the method of NSDictionary that sets an object of a key, objectForKey:. Be careful
not to confuse this with setValue:forKey:; that's for a completely different thing, Key Value Coding
Shorthand
cars[@"Lamborghini"] = lamborghini;
This is the syntax that you use for dictionaries in most other languages, such as C#, Java, and JavaScript. It's much
more convenient than the standard syntax, and arguably more readable (especially if you code in these other
languages), but of course, it isn't standard. It's also only available in newer versions of Objective-C
Standard
Car * lamborghini = [cars objectForKey:@"Lamborghini"];
Just like any other object, call the method of NSDictionary that gives you an object for a key, objectForKey:. Be
careful not to confuse this with valueForKey:; that's for a completely different thing, Key Value Coding
Shorthand
Car * lamborghini = cars[@"Lamborghini"];
This is the syntax that you use for dictionaries in most other languages, such as C#, Java, and JavaScript. It's much
more convenient than the standard syntax, and arguably more readable (especially if you code in these other
languages), but of course, it isn't standard. It's also only available in newer versions of Objective-C
//check if the dictionary contains the key you are going to modify. In this example, @"Sam"
if (dict[@"name1"] != nil) {
//there is an entry for Key name1
}
else {
//There is no entry for name1
}
Example:
NSDictionary stockSymbolsDictionary = @{
Creates and returns a mutable dictionary, initially giving it enough allocated memory to hold a given number of
entries.
- init
+ dictionaryWithSharedKeySet:
Creates a mutable dictionary which is optimized for dealing with a known set of keys.
Output
{
key1 = Easy;
key2 = Tutorials;
key3 = Website;
}
- setObject:forKey:
{
Key1 = Eezy;
}
- setObject:forKeyedSubscript:
Output
{
Key1 = Easy;
}
Removes a given key and its associated value from the dictionary.
OUTPUT
{
key2 = Tutorials;
}
- removeAllObjects
OUTPUT
- removeObjectsForKeys:
OUTPUT
{
key2 = Tutorials;
}
The downside for this situation is that your NSDate is almost completely "naked" and what you need to do is to
create: day, month, year, second and time zone in order to this object to "play along" with other NSDate types.
For the sake of the example let's say that hourAndMinute is the NSDate type that is composed from hour and
minute format:
Note:
Returns an NSDate object initialized relative to 00:00:00 UTC on 1 January 2001 by a given number of
seconds.
NSDate also provides an easy way to create an NSDate equal to the current date and time:
It is also possible to create an NSDate a given amount of seconds from the current date and time:
- (BOOL)isEqualToDate:(NSDate *)anotherDate
- (NSDate *)earlierDate:(NSDate *)anotherDate
- (NSDate *)laterDate:(NSDate *)anotherDate
- (NSComparisonResult)compare:(NSDate *)anotherDate
Consider the following example using 2 dates, NSDate date1 = July 7, 2016 and NSDate date2 = July 2, 2016:
if ([date1 isEqualToDate:date2]) {
//Here it returns false, as both dates are not equal
}
We can also use the earlierDate: and laterDate: methods of the NSDate class:
//Succeeds
//Comes here if date1 is later than date2. In our case it will come here
}
- initWithString:
+ URLWithString:relativeToURL:
- initWithString:relativeToURL:
+ fileURLWithPath:isDirectory:
- initFileURLWithPath:isDirectory:
+ fileURLWithPath:
- initFileURLWithPath:
Designated Initializer
+ fileURLWithPathComponents:
+ URLByResolvingAliasFileAtURL:options:error:
+ URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:
- initByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:
+ fileURLWithFileSystemRepresentation:isDirectory:relativeToURL:
- getFileSystemRepresentation:maxLength:
- initFileURLWithFileSystemRepresentation:isDirectory:relativeToURL:
If the receiver represents the root path, this property contains a copy of the original URL. If the URL has multiple
path extensions, only the last one is removed.
2. URLByAppendingPathExtension:
Returns a new URL made by appending a path extension to the original URL.
Example:
NSUInteger count = 0;
NSString *filePath = nil;
do {
NSString *extension = ( NSString *)UTTypeCopyPreferredTagWithClass((
CFStringRef)AVFileTypeQuickTimeMovie, kUTTagClassFilenameExtension);
NSString *fileNameNoExtension = [[asset.defaultRepresentation.url
// Setting a timeout
request.timeoutInterval = 20.0;
// This is how we set header fields
[request setValue:@"application/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
From Int:
int i = 1;
NSData *data = [NSData dataWithBytes: &i length: sizeof(i)];
+ dataWithContentsOfURL:
+ dataWithContentsOfURL:options:error:
+ dataWithData:
- initWithBase64EncodedData:options:
- initWithBase64EncodedString:options:
- initWithBase64Encoding:
- initWithBytesNoCopy:length:
- initWithBytesNoCopy:length:deallocator:
- initWithBytesNoCopy:length:freeWhenDone:
- initWithContentsOfFile:
- initWithContentsOfFile:options:error:
- initWithContentsOfMappedFile:
- initWithContentsOfURL:
- initWithContentsOfURL:options:error:
- initWithData:
return hexString;
}
Decoding:
options:NSRegularExpressionCaseInsensitive error:&error];
The output will show that the first string is a phone number and the second one isn't.
options:NSRegularExpressionCaseInsensitive
error:&error];
if (!jsonArray) {
NSLog(@"Error parsing JSON: %@", e);
} else {
for(NSDictionary *item in jsonArray) {
NSLog(@"Item: %@", item);
}
}
Output:
Item: {
id = 1;
name = sam;
}
//Parsing:
Sample response:
json: {
MESSAGE = "Test Message";
RESPONSE =(
{
email = "[email protected]";
id = 15;
phone = 1234567890;
name = Staffy;
}
);
STATUS = SUCCESS;
}
+autoupdatingCurrentCalendar returns the current logical calendar for the current user.
- setFirstWeekday: Sets the index of the first weekday for the receiver.
- setMinimumDaysInFirstWeek: Sets the minimum number of days in the first week of the receiver.
- dateFromComponents: Returns a new NSDate object representing the absolute time calculated from given
components.
[attributedString addAttribute:NSUnderlineStyleAttributeName
value:[NSNumber numberWithInt:NSUnderlineStyleDouble]
range:NSMakeRange(7, attributedStr.length)];
[attributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor blueColor]
range:NSMakeRange(6,attributedStr.length)];
Output:
A common application is to use this to display a string and adding custom kerning / letter-spacing.
This would be achieved as follows (where label is a UILabel), giving a different kerning for the word "kerning"
NSMutableAttributedString *attributedString;
attributedString = [[NSMutableAttributedString alloc] initWithString:@"Apply kerning"];
[attributedString addAttribute:NSKernAttributeName value:@5 range:NSMakeRange(6, 7)];
[label setAttributedText:attributedString];
Here we have firstsecondthird string so in first we have set range (0,5) so from starting first character to fifth
character it will display in green text color.
By taking a timer as a parameter in said function, you can access the userInfo property.
NSDictionary *dictionary = @{
@"Message" : @"Hello, world!"
}; //this dictionary contains a message
[NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(doSomething)
userInfo:dictionary
repeats:NO]; //the timer contains the dictionary and later calls the function
...
- (void) doSomething:(NSTimer*)timer{
//the function retrieves the message from the timer
NSLog("%@", timer.userInfo["Message"]);
}
[NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(doSomething)
userInfo:nil
repeats:NO];
Setting the repeats parameter to false/NO indicates that we want the timer to fire only once. If we set this to
true/YES, it would fire every five seconds until manually invalidated.
This will stop the timer from firing. Must be called from the thread the timer was created in, see Apple's notes:
You must send this message from the thread on which the timer was installed. If you send this message
from another thread, the input source associated with the timer may not be removed from its run loop,
which could prevent the thread from exiting properly.
Setting nil will help you next to check whether it's running or not.
if(timer) {
[timer invalidate];
timer = nil;
Calling the fire method causes an NSTimer to perform the task it would have usually performed on a schedule.
In a non-repeating timer, this will automatically invalidate the timer. That is, calling fire before the time interval is
up will result in only one invocation.
In a repeating timer, this will simply invoke the action without interrupting the usual schedule.
This class have all basic property of Objective'C class object like:
self.
- (instancetype)init
+ (instancetype)new
+ (instancetype)alloc
- (id)copy;
- (id)mutableCopy;
- (BOOL)isEqual:(id)object
superclass
- (BOOL)isKindOfClass:(Class)aClass
- (instancetype)retain OBJC_ARC_UNAVAILABLE;
- (instancetype)autorelease OBJC_ARC_UNAVAILABLE;
- (NSUInteger)retainCount
//Create a Custom class with properties for firstName & lastName of type NSString *,
//and age, which is an NSUInteger.
If you can recreate those values at runtime (by downloading from the Internet, by doing calculations, whatever)
then NSCache may suit your needs. If the data cannot be recreated (e.g. it's user input, it is time-sensitive, etc.) then
you should not store it in an NSCache because it will be destroyed there.
FOR SAVING:
// saving an NSString
[prefs setObject:txtUsername.text forKey:@"userName"];
[prefs setObject:txtPassword.text forKey:@"password"];
[prefs synchronize];
FOR RETRIEVING
// getting an NSString
NSString *savedUsername = [prefs stringForKey:@"userName"];
NSString *savedPassword = [prefs stringForKey:@"password"];
This line
Can be replaced by
fruit[1];
If the index of the subscript equals the count of the array, the element will be appended to the array.
- (id)objectAtIndexedSubscript:(NSUInteger)idx
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx
- (id)objectForKeyedSubscript:(id)key
- (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying>)key
This technique can be used to augment or "patch" existing methods which you cannot edit directly, such as
methods of system-provided classes.
In the following example, the -[NSUserDefaults synchronize] method is augmented to print the execution time of
the original implementation.
IMPORTANT: Many people try to do swizzling using method_exchangeImplementations. However, this approach is
dangerous if you need to call the method you're replacing, because you'll be calling it using a different selector than
it is expecting to receive. As a result, your code can break in strange and unexpected ways—particularly if multiple
parties swizzle an object in this way. Instead, you should always do swizzling using setImplementation in
conjunction with a C function, allowing you to call the method with the original selector.
#import "NSUserDefaults+Timing.h"
#import <objc/runtime.h> // Needed for method swizzling
@implementation NSUserDefaults(Timing)
+ (void)load
{
Method originalMethod = class_getInstanceMethod([self class], @selector(synchronize:));
IMP swizzleImp = (IMP)new_synchronize;
old_synchronize = method_setImplementation(originalMethod, swizzleImp);
}
@end
return returnValue;
}
If you need to swizzle a method that takes parameters, you just add them as additional parameters to the function.
For example:
...
...
...
}
The associated object is automatically released by the runtime once the target object is deallocated.
#import <objc/runtime.h>
id target = ...;
id payload = ...;
objc_setAssociateObject(target, &key, payload, OBJC_ASSOCIATION_RETAIN);
// Other useful values are OBJC_ASSOCIATION_COPY
// and OBJ_ASSOCIATION_ASSIGN
#import <objc/objc.h>
@implementation Example
- (double)invert:(double)value {
return 1 / value;
}
@end
// Calls the selector on the object. Expects the method to have one double argument and return a
double.
double performSelectorWithMsgSend(id object, SEL selector, double value) {
// We declare pointer to function and cast `objc_msgSend` to expected signature.
// WARNING: This step is important! Otherwise you may get unexpected results!
double (*msgSend)(id, SEL, double) = (typeof(msgSend)) &objc_msgSend;
// The implicit arguments of self and _cmd need to be passed in addition to any explicit
arguments.
return msgSend(object, selector, value);
}
// Does the same as the above function, but by obtaining the method's IMP.
double performSelectorWithIMP(id object, SEL selector, double value) {
// Get the method's implementation.
IMP imp = class_getMethodImplementation([self class], selector);
// Cast it so the types are known and ARC can work correctly.
double (*callableImp)(id, SEL, double) = (typeof(callableImp)) imp;
int main() {
Example *e = [Example new];
objc_msgSend works by obtaining the IMP for the method and calling that. The IMPs for the last several methods
called are cached, so if you're sending an Objective-C message in a very tight loop you can get acceptable
performance. In some cases, manually caching the IMP can give slightly better performance, although this is a last
resort optimization.
}];
You can use the for ... in syntax to go through each item of the array, automatically starting with the first at
index 0 and stopping with the last item:
// item: fast
// item: enumeration
// item: in objc
It is good practice to add a prefix (PF) to the method to ensure we don't overwrite any future NSArray methods.
- (NSArray *)pf_filterSmaller:(double)number;
@end
- (NSArray *)pf_filterSmaller:(double)number
{
NSMutableArray *result = [NSMutableArray array];
for (id val in self)
{
if ([val isKindOfClass:[NSNumber class] && [val doubleValue] >= number)
{
[result addObject:val];
}
}
return [result copy];
}
@end
@end
+(UIColor *)xyz_indigoColor
{
return [UIColor colorWithRed:75/255.0f green:0/255.0f blue:130/255.0f alpha:1.0f];
}
@end
Note that the property declaration of retain, nonatomic matches the last argument to
objc_setAssociatedObject. See Attach object to another existing object for explanations.
#import <objc/runtime.h>
@end
@dynamic screenName;
- (NSString *)screenName {
return objc_getAssociatedObject(self, @selector(screenName));
}
- (void)setScreenName:(NSString *)screenName {
objc_setAssociatedObject(self, @selector(screenName), screenName,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
For example we want to set some custom fonts. Let's create a category that add functionality to UIFont class. Open
your XCode project, click on File -> New -> File and choose Objective-C file, click Next enter your category name
say "CustomFont" choose file type as Category and Class as UIFont then Click "Next" followed by "Create."
Click "UIFont+CustomFonts.h" to view the new category's header file. Add the following code to the interface to
declare the method.
+(UIFont *)productSansRegularFontWithSize:(CGFloat)size;
@end
Click "UIFont+CustomFonts.m" to view the category's implementation file. Add the following code to create a
method that will set ProductSansRegular Font.
+(UIFont *)productSansRegularFontWithSize:(CGFloat)size{
#import "UIFont+CustomFonts.h"
It is also possible to declare optional methods. These method can be implemented only if needed.
@protocol NewProtocol
- (void)protocolMethod:(id)argument;
@optional
- (id)anotherMethod;
@end
In this case, only anotherMethod is marked as optional; the methods without the @optional directive are assumed
to be required.
The @optional directive applies to methods that follow, until the end of the protocol definition or, until another
directive is found.
@protocol NewProtocol
- (void)protocolMethod:(id)argument;
@optional
- (id)anotherMethod;
- (void)andAnotherMethod:(id)argument;
@required
- (void)lastProtocolMethod;
@end
This last example defines a protocol with two optional methods and two required methods.
@protocol Person;
@protocol Person
- (NSString *)gender;
- (NSString *)name;
@end
It's useful when you don't need to know protocols details until you import that file with protocol definition. So, your
class header file stays clear and contains details of the class only.
This means that any instance of NewClass will respond to methods declared in its interface but also it will provide
an implementation for all the required methods of NewProtocol.
It is also possible for a class to conform to multiple protocols, by separating them with comma.
Like when conforming to a single protocol, the class must implement each required method of each protocols, and
each optional method you choose to implement.
@protocol NewProtocol
- (void)protocolMethod:(id)argument;
- (id)anotherMethod;
@end
[MyClass conformsToProtocol:@protocol(MyProtocol)];
Instance of ViewB is created inside ViewA, so ViewA can send message to ViewB's instance, but for the reverse to
happen we need to implement delegation (so that using delegate ViewB's instance could send message to ViewA)
@protocol ViewBDelegate
-(void) exampleDelegateMethod;
@end
-(void) anyFunction
{
// create Class ViewB's instance and set the delegate
[viewB setDelegate:self];
}
-(void) exampleDelegateMethod
{
// will be called by Class ViewB's instance
}
-(void) callDelegateMethod
{
[delegate exampleDelegateMethod];
//assuming the delegate is assigned otherwise error
}
If you declare a block type as a typedef, you can then use the new type name instead of the full description of the
arguments and return values. This defines Operation as a block that takes two doubles and returns a double.
- (double)doWithOperation:(Operation)operation
first:(double)first
second:(double)second;
or as a variable type:
// Returns 3.0
[self doWithOperation:addition
first:1.0
second:2.0];
@end
When assigning, since self retains blockProperty, block should not contain a strong reference to self. Those
mutual strong references are called a "retain cycle" and will prevent the release of either object.
It is highly unlikely, but self might be deallocated inside the block, somewhere during the execution. In this case
weakSelf becomes nil and all messages to it have no desired effect. This might leave the app in an unknown state.
This can be avoided by retaining weakSelf with a __strong ivar during block execution and clean up afterward.
square(5); // resolves to 25
square(-7); // resolves to 49
NSMutableDictionary *localStatus;
void (^logStatus)() = ^(void){ [MYUniversalLogger logCurrentStatus:localStatus]};
logStatus(); // this will call the block with the current localStatus
NSLog(@"%@",self.results);
}];
[task resume];
if([elementName isEqualToString:@"GeocodeResponse"]){
self.results=[[NSMutableArray alloc] init];
}
if([elementName isEqualToString:@"formatted_address"]){
self.parsedString=[[NSMutableString alloc] init];
}
if(self.parsedString){
[self.parsedString appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet
whitespaceAndNewlineCharacterSet]]];
}
if([elementName isEqualToString:@"formatted_address"]){
[self.results addObject:self.parsedString];
self.parsedString=nil;
}
Class methods can be called by class name itself .Class methods are declared and defined by using + (plus)sign .
- (void)testInstanceMethod;
@end
+ (void)aClassMethod;
@end
[MyClass aClassMethod];
class methods are the convenience methods on many Foundation classes like [NSString's
+stringWithFormat:] or NSArray's +arrayWithArray
int main()
{
NSLog(@"File :%s\n", __FILE__ );
NSLog(@"Date :%s\n", __DATE__ );
NSLog(@"Time :%s\n", __TIME__ );
NSLog(@"Line :%d\n", __LINE__ );
NSLog(@"ANSI :%d\n", __STDC__ );
return 0;
}
When the above code in a file main.m is compiled and executed, it produces the following result:
Objectives of Concurrency
Define Tasks, Define Rules and let the system take the responsibility of performing them.
Improve responsiveness by ensuring that the main thread is free to respond to user events.
DISPATCH QUEUES
Grand central dispatch – dispatch queues allows us to execute arbitrary blocks of code either asynchronously or
synchronously All Dispatch Queues are first in – first out All the tasks added to dispatch queue are started in the
order they were added to the dispatch queue.
The first argument of NSLog is an NSString containing the log message format. The rest of the parameters are used
as values to substitute in place of the format specifiers.
The formatting works exactly the same as printf, except for the additional format specifier %@ for an arbitrary
Objective-C object. This:
NSLog(@"%@", object);
is equivalent to:
The message that gets printed by calling NSLog has the following format when viewed in Console.app:
#ifdef DEBUG
#define DLog(...) NSLog(__VA_ARGS__)
#else
#define DLog(...)
#endif
To use:
In debug builds, DLog will call NSLog. In release builds, DLog will do nothing.
If the variable is not an NSString, the program will crash, because NSLog expects an NSString.
If the variable is an NSString, it will work unless your string contains a %. NSLog will parse the % sequence as a
format specifier and then read a garbage value off the stack, causing a crash or even executing arbitrary code.
Instead, always make the first argument a format specifier, like this:
NSLog(@"%@", anObjectVariable);
NSLog(@"%d", anIntegerVariable);
Output:
NSLog outputs the date, time, process name, process ID, and thread ID in addition to the log message. printf just
outputs the message.
Some format-specifiers in printf vs NSLog are different. For example when including a nested string, the
following differences incur:
Will log the file, line number and function data along with any variables you want to log. This can make the log lines
much longer, particularly with verbose file and method names, however it can help to speed up error diagnostics.
You can also wrap this in a Macro (store this in a Singleton or where you'll need it most);
#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
Output:
Another way to print boolean value is to cast it to integer, achieving a binary output (1=yes, 0=no).
Output:
Errors are user-level issues like trying load a file that doesn’t exist. Because errors are expected during the normal
execution of a program.
Example:
Output:
Here are some details: *** -[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]
...
-(void)setAngles:(NSArray *)_angles {
self.angles = _angles;
NSAssert((self.angles.count == 3), @"Triangles must have 3 angles. Array '%@' has %i",
self.angles, (int)self.angles.count);
These assertions make sure that you don't give a triangle incorrect angles, by throwing an exception if you do. If
they didn't throw an exception than the triangle, not being a true triangle at all, might cause some bugs in later
code.
NSNumber
Old way:
Modern way:
Note: you can also store BOOL values in NSNumber objects using @YES, @NO or @(someBoolValue);
NSArray
Old way:
Modern way:
NSDictionary
Old way:
Modern way:
Old way:
Modern way:
You can also insert objects into arrays and set objects for keys in dictionaries in a cleaner way:
Old way:
Modern way:
mutableArray[1] = @"NewValue";
mutableArray[[mutableArray count]] = @"NewValue";
mutableDictionary[@"NewKey"] = @"NewValue";
+ (instancetype)shared {
return _shared;
}
+ (instancetype)sharedInstance;
-(instancetype)init NS_UNAVAILABLE;
-(instancetype)new NS_UNAVAILABLE;
@end
//MySingletonClass.m
@implementation MySingletonClass
+ (instancetype)sharedInstance
{
static MySingletonClass *_sharedInstance = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedInstance = [[self alloc]init];
});
return _sharedInstance;
}
-(instancetype)init
{
self = [super init];
@implementation MySingletonClass
+ (instancetype)sharedInstance
{
static MySingletonClass *_sharedInstance = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedInstance = [[self alloc] initClass];
});
return _sharedInstance;
}
-(instancetype)initClass
{
self = [super init];
if(self)
{
//Do any additional initialization if required
}
return self;
}
- (instancetype)init
{
@throw [NSException exceptionWithName:@"Not designated initializer"
reason:@"Use [MySingletonClass sharedInstance]"
userInfo:nil];
return nil;
}
@end
- (void)createThread {
[self performSelectorInBackground:@selector(threadMainWithOptionalArgument:)
withObject:someObject];
}
- (void)threadMainWithOptionalArgument:(id)argument {
// To avoid memory leaks, the first thing a thread method needs to do is
// create a new autorelease pool, either manually or via "@autoreleasepool".
@autoreleasepool {
// The thread code should be here.
}
}
The NSThread class supports a method called cancel that can be called from any thread, which then sets the
cancelled property to YES in a thread-safe way. The thread implementation can query (and/or observe) the
cancelled property and exit its main method. This can be used to gracefully shut down a worker thread.
// Add properties for values that need to be passed from the caller to the new
// thread. Caller must not modify these once the thread is started to avoid
// threading issues (or the properties must be made thread-safe using locks).
@property NSInteger someProperty;
@end
@implementation MyThread
- (void)main
{
@autoreleasepool {
// The main thread method goes here
NSLog(@"New thread. Some property: %ld", (long)self.someProperty);
}
}
@end
- (void)testReverseString{
NSString *originalString = @"hi_my_name_is_siddharth";
NSString *reversedString = [self.someObject reverseString:originalString];
NSString *expectedReversedString = @"htrahddis_si_eman_ym_ih";
XCTAssertEqualObjects(expectedReversedString, reversedString, @"The reversed string did not match
the expected reverse");
}
Feed the dummy data to the method under test if required & then compare the expected & actual
results.
- (void)testPerformanceReverseString {
NSString *originalString = @"hi_my_name_is_siddharth";
[self measureBlock:^{
[self.someObject reverseString:originalString];
}];
}
- (void)testPerformanceOfAsynchronousBlock {
[self measureMetrics:@[XCTPerformanceMetric_WallClockTime] automaticallyStartMeasuring:YES
forBlock:^{
These performance measure block gets executed for 10 times consecutively & then the average is calculated,
& on the basis of this average performance result gets created & baseline is accepted for further evaluation.
The performance result is compared with the previous test results & baseline with a customizable max
standard deviation.
By calling a method whose name begins with alloc, new, copy or mutableCopy. For example:
That means that you are responsible for releasing these objects when you are done with them.
For example:
For example when you implement an accessor or an init method to take ownership:
- (void)setStringValue:(NSString *)stringValue {
[_privateStringValue release]; // Release the old value, you no longer need it
[stringValue retain]; // You make sure that this object does not get deallocated outside
of your scope.
_privateStringValue = stringValue;
}
3. When you no longer need it, you must relinquish ownership of an object you own
That means when you didn't take ownership of an object you don't release it.
5. Autoreleasepool
The autoreleasepool is a block of code that releases every object in the block that received an autorelease
message.
@autoreleasepool {
NSString* string = [NSString stringWithString:@"We don't own this object"];
}
We have created a string without taking ownership. The NSString method stringWithString: has to make
sure that the string is correctly deallocated after it is no longer needed. Before the method returns the newly
created string calls the autorelease method so it does not have to take ownership of the string.
It is necessary to use autoreleasepool blocks because you sometimes have objects that you don't own (the
fourth rules does not always apply).
Automatic reference counting takes automatically care of the rules so you don't have to.
The sample program from Manual Memory Management looks like this with ARC:
@implementation MyObject
@synthesize property = _property;
- (id)initWithProperty:(NSString *)property {
if (self = [super init]) {
_property = property;
}
return self;
}
- (NSString *)property {
return property;
}
- (void)setProperty:(NSString *)property {
_property = property;
}
@end
int main() {
MyObject *obj = [[MyObject alloc] init];
[obj setProperty:@"value"];
}
You are still able to override the dealloc method to clean up resources not handled by ARC. Unlike when using
manual memory management you do not call [super dealloc].
-(void)dealloc {
//clean up
}
Object references are always strong by default. But you can explicitly specify that they're strong:
A strong reference means that while that reference exists, you are retaining the object.
@implementation MyObject
@synthesize property = _property;
- (id)initWithProperty:(NSString *)property {
if (self = [super init]) {
// Grab a reference to property to make sure it doesn't go away.
// The reference is released in dealloc.
_property = [property retain];
}
return self;
- (NSString *)property {
return [[property retain] autorelease];
}
- (void)setProperty:(NSString *)property {
// Retain, then release. So setting it to the same value won't lose the reference.
[property retain];
[_property release];
_property = property;
}
- (void)dealloc {
[_property release];
[super dealloc]; // Don't forget!
}
@end
int main() {
// create object
// obj is a reference that we need to release
MyObject *obj = [[MyObject alloc] init];