iOS Flashcards

1
Q

Difference between messaging and function calling?

A

In the messaging structure (which evolved from Smalltalk, the origin of messaging) the runtime decides which code gets executed. With function calling, the compiler decides.

When Polymorphism is used in function calling, a runtime lookup as a virtual table is used. In messaging the compiler doesnt care about the type of object being messaged, that is looked up at runtime too.

Advantage of messaging: The App’s performance benefits of runtime updates directly, whereas a compile time language has to be recompiled to benefit from updates.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What is the runtime?

A

The runtime is a dynamic library that contains all the data structures and functions that are required for the object oriented features of Objective-C, like all the memory management methods. The code from the app is linked to that library of the runtime, which does the heavy lifting, instead of the compiler.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Describe Pointers

A

Obj C uses pointers to denote an object, so variables are holding references to an object.
The syntax: NSString * myString = @”Hello”

The pointers are allocated on the stack, and point to some memory, allocated on the heap, containing an NSString Object. All Objects must be allocated in the heap space, never on the stack.

If another variable points to the same memory, the object is NOT getting copied, rather both variables point to the same object:
NSString * anotherString = myString;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

bitwise AND

A

&
Example: 0010110 & 1 = 0
Shows if the least significant bit is set.

Performs an AND on each bit position between 2
0101 (decimal 5)
AND 0011 (decimal 3)
= 0001 (decimal 1)

The operation may be used to determine whether a particular bit is set (1) or clear (0). For example, given a bit pattern 0011 (decimal 3), to determine whether the second bit is set we use a bitwise AND with a bit pattern containing 1 only in the second bit:
1010 AND
0010 (bitmask)
=
0010
Because the result 0010 is non-zero, we know the second bit in the original pattern was set. This is often called bit masking.

If we store the result, this may be used to clear selected bits in a register. Given the example 0110 (decimal 6), the second bit may be cleared by using a bitwise AND with the pattern that has a zero only in the second bit:

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What is a: retain cycle?

A

Two objects having a strong pointer to each other and preventing the retain count ever reaching 0. This is a form of memory leak. It gets fixed by using weak references on the non-owning relationship. The weak attribute will set the property to nil if the reference gets destroyed.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Code for binary search:

A

binary_search(A, target):
lo = 1, hi = size(A)
while lo

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What is Cocoa, what are its Frameworks?

A

Cocoa is an application environment, containing object oriented frameworks, a runtime system and a development environment. Frameworks in Cocoa are:

  • Foundation
  • AppKit
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Describe Objective C

A

Objective C is a object oriented language, based on C. It is more dynamic than other languages, shifting the responsibility of symbol resolution from compile time to runtime, which gives the user more control.
Its Dynamism consists of:
· Dynamic typing—determining the class of an object at runtime
· Dynamic binding—determining the method to invoke at runtime
· Dynamic loading—adding new modules to a program at runtime

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Differences between Obj-C and C++/C

A

· The Objective-C class allows a method and a variable with the exact same name. In C++, they must be different.
· Objective-C does not have a constructor or destructor. Instead it has init and dealloc methods, which must be called explicitly.
· Objective-C uses + and - to differentiate between class method (known as factory method in Java) and instance methods, C++ uses static to specify a factory method.
· Multiple inheritance is not allowed in Obj-C, however we can use protocol to some extent.
· Obj-C has runtime binding leading to dynamic linking.
· Obj-C has categories.
· Objective-C has a work-around for method overloading, but none for operator overloading. In Objective-C the message overloading is faked by naming the parameters. C++ actually does the same thing but the compiler does the name mangling for us. In Objective-C, we have to mangle the names manually. If you go in deep you will see a complete method names are as : addA:withB: which is a selector and : is used for parameter.
· One of C++’s advantages and disadvantages is automatic type coercion.
· Objective-C also does not allow stack based objects. Each object must be a pointer to a block of memory.
· Another feature C++ has that is missing in Objective-C is references. Because pointers can be used wherever a reference is used, there isn’t much need for references in general.
· Templates are another feature that C++ has that Objective-C doesn’t. Templates are needed because C++ has strong typing and static binding that prevent generic classes, such as List and Array.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

AppKit

A

AppKit is a framework that contains all UI elements that are typically used to build an application interface, like buttons, scrollers, textfields, lists, windows, menus, panels. It is already optimized to clip on screen, draw efficiently, clear graphic buffers, respond to events and contains a default visualization.
It can either be setup visually by using Interface Builder, programmatically or subclassed for custom UI.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Foundation

A

Foundation is a base layer of Objective-C classes, that provides primitive classes and datastructures, a small set of utility classes, introduces consistent conventions for things such as deallocation, supports Unicode strings, object persistence, and object distribution, and provides a level of OS independence, to enhance portability.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Dynamic vs Static Typing

A
Languages that use static typing declare their objects' type at compile time, whereas languages like Obj-C with dynamic typing resolve their objects' class type at runtime. 
Declaring a type for a variable is only used for a build time error check but can be broken at runtime and also just declared as "id" which leaves the type open.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Describe Selectors

A

Selectors 1) refer to the name of a method when it’s used in a source-code message to an object.
2) It also refers to the unique identifier that replaces the name when the source code is compiled. Compiled selectors are of type SEL. All methods with the same name have the same selector.
You can use a selector to invoke a method on an object—this provides the basis for the implementation of the target-action design pattern in Cocoa.
[friend performSelector:@selector(gossipAbout:) withObject:aNeighbor];
is equivalent to:
[friend gossipAbout:aNeighbor];

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Class introspection

A

· Determine whether an objective-C object is an instance of a class
[obj isMemberOfClass:someClass];
· Determine whether an objective-C object is an instance of a class or its descendants
[obj isKindOfClass:someClass];
· The version of a class
[MyString version]
· Find the class of an Objective-C object
Class c = [obj1 class]; Class c = [NSString class];
· Verify 2 Objective-C objects are of the same class
[obj1 class] == [obj2 class]

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What is a Category?

A

import “Car+Maintenance.h”

A category allows you to add methods to an existing class without subclassing or changing the actual object —even to one for which you do not have the source.

They are often used to add methods to existing classes, such as NSString or your own custom objects, and in shared frameworks to preserve base classes and add functionality.

Categories work just like normal class definitions in that they are composed of an interface and an implementation. To add a new category to your Xcode project, create a new file and choose the Objective-C category template under iOS > Cocoa Touch.

The only restriction on category names is that they don’t conflict with other categories on the same class. The canonical file-naming convention is to use the class name and the category name separated by a plus sign, so you should find a Car+Maintenance.h and a Car+Maintenance.m in Xcode’s Project Navigator after saving the above category.

As you can see in Car+Maintenance.h, a category interface looks exactly like a normal interface, except the class name is followed by the category name in parentheses.

// Car+Maintenance.h
#import "Car.h"

@interface Car (Maintenance)

At runtime, these methods become part of the Car class. Even though they’re declared in a different file, you will be able to access them as if they were defined in the original Car.h.

Of course, you have to implement the category interface for the above methods to actually do anything.

It’s important to note that a category can also be used to override existing methods in the base class (e.g., the Car class’s drive method), but you should never do this. The problem is that categories are a flat organizational structure. If you override an existing method in Car+Maintenance.m, and then decide you want to change its behavior again with another category, there is no way for Objective-C to know which implementation to use. Subclassing is almost always a better option in such a situation.

Saving properties in categories:

objc_getAssociatedObject and objc_getAssociatedObject require a key to store the object. Such key is required to be a constant void pointer. So in the end we just need a fixed address that stays constant over time.

It turns out that the @selector implementation provides just about what we need, since it uses fixed addresses.

We can therefore just get rid of the key declaration and simply use our property’s selector address.

So if you are associating at runtime a property like

@property (nonatomic, retain) id anAssociatedObject;
we can provide dynamic implementations for its getter/setter that look like

  • (void)setAnAssociatedObject:(id)newAssociatedObject {
    objc_setAssociatedObject(self, @selector(anAssociatedObject), newAssociatedObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
- (id)anAssociatedObject {
    return objc_getAssociatedObject(self, @selector(anAssociatedObject));
}
Very neat and definitely cleaner than defining an extra static variable key for every associated object.

Traditional way:

.h-file

@interface NSObject (LaserUnicorn)
@property (nonatomic, strong) LaserUnicorn *laserUnicorn;
@end

.m-file

static void * LaserUnicornPropertyKey = &LaserUnicornPropertyKey;

@implementation NSObject (LaserUnicorn)

- (LaserUnicorn *)laserUnicorn {
    return objc_getAssociatedObject(self, LaserUnicornPropertyKey);
}
  • (void)setLaserUnicorn:(LaserUnicorn *)unicorn {
    objc_setAssociatedObject(self, LaserUnicornPropertyKey, unicorn, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    @end

Usage: Just like a normal property - accessible with dot-notation

NSObject *myObject = [NSObject new];
myObject.laserUnicorn = [LaserUnicorn new];
NSLog(@”Laser unicorn: %@”, myObject.laserUnicorn);

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Adding properties to Objects, dynamically

A

import

objc_getAssociatedObject and objc_getAssociatedObject require a key to store the object. Such key is required to be a constant void pointer. So in the end we just need a fixed address that stays constant over time.

It turns out that the @selector implementation provides just about what we need, since it uses fixed addresses.

We can therefore just get rid of the key declaration and simply use our property’s selector address.

So if you are associating at runtime a property like

@property (nonatomic, retain) id anAssociatedObject;
we can provide dynamic implementations for its getter/setter that look like

  • (void)setAnAssociatedObject:(id)newAssociatedObject {
    objc_setAssociatedObject(self, @selector(anAssociatedObject), newAssociatedObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
- (id)anAssociatedObject {
    return objc_getAssociatedObject(self, @selector(anAssociatedObject));
}
Very neat and definitely cleaner than defining an extra static variable key for every associated object.

Traditional way:

.h-file

@interface NSObject (LaserUnicorn)
@property (nonatomic, strong) LaserUnicorn *laserUnicorn;
@end

.m-file

static void * LaserUnicornPropertyKey = &LaserUnicornPropertyKey;

@implementation NSObject (LaserUnicorn)

- (LaserUnicorn *)laserUnicorn {
    return objc_getAssociatedObject(self, LaserUnicornPropertyKey);
}
  • (void)setLaserUnicorn:(LaserUnicorn *)unicorn {
    objc_setAssociatedObject(self, LaserUnicornPropertyKey, unicorn, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    @end

Usage: Just like a normal property - accessible with dot-notation

NSObject *myObject = [NSObject new];
myObject.laserUnicorn = [LaserUnicorn new];
NSLog(@”Laser unicorn: %@”, myObject.laserUnicorn);

17
Q

Proxy

A

TODO

NSProxy is an abstract superclass defining an API for objects that act as stand-ins for other objects or for objects that don’t exist yet. Typically, a message to a proxy is forwarded to the real object or causes the proxy to load (or transform itself into) the real object. Subclasses of NSProxy can be used to implement transparent distributed messaging (for example, NSDistantObject) or for lazy instantiation of objects that are expensive to create.

18
Q

Category VS Inheritance

A

Category allows adding methods only; no data members can be added as in Inheritance both data and methods can be added.
Category’s scope is full application whereas inheritance’s scope that particular file. However in new compilers using associatedObjects you can add data members using category.

Why category is better than inheritance?
       If category is used, you can use same class, no need to remember a new class-name. Category created on a base class is available on sub classes.
19
Q

Fast enumeration

A

Fast enumeration is a language feature that allows you to enumerate over the contents of a collection. (Your code will also run faster because the internal implementation reduces message send overhead and increases pipelining potential.)
Enum is preferred over loop for the same reason.

20
Q

How much more values can you store with each more bit?

A

Double as before.

Since I can show all before combinations, with the new bit on 0, and then the same as much, with the new on 1.

So 3 bits have 8 possibilities. 4 bits have 16.

21
Q

What happens if a child and parent are holding strong references of each other?

A

Strong reference cycle. A child should always have a weak reference of the parent.

22
Q

Difference between:

  • bundle identifier
  • App ID
  • Apple ID
  • Team ID
A

Bundle ID

  • A reverse-domain name style string
  • Defined in Xcode
  • Uniquely identifies an Application Bundle on a device or simulator
  • Must have a matching App ID registered with Apple in order to deploy
  • Used to distinguish app updates vs. new apps

App ID
- An object in Member Center with lots of metadata:
App ID Description
App ID Prefix
App ID Suffix
App Services
Multiple apps can share the same App ID. The App ID does not uniquely identify an application.

Apple ID
A unique integer assigned by Apple when an app is first created in iTunes Connect.

Team ID

  • A 10 character alphanumeric hash
  • Unique to every Developer Account (as in the account that costs $99/yr, not every developer on the account)
23
Q

Difference between:

  • bundle identifier
  • App ID
  • Apple ID
  • Team ID
A

Bundle ID

  • A reverse-domain name style string
  • Defined in Xcode
  • Uniquely identifies an Application Bundle on a device or simulator
  • Must have a matching App ID registered with Apple in order to deploy
  • Used to distinguish app updates vs. new apps

App ID
- An object in Member Center with lots of metadata:
App ID Description
App ID Prefix
App ID Suffix
App Services
Multiple apps can share the same App ID. The App ID does not uniquely identify an application.

Apple ID
A unique integer assigned by Apple when an app is first created in iTunes Connect.

Team ID

  • A 10 character alphanumeric hash
  • Unique to every Developer Account (as in the account that costs $99/yr, not every developer on the account)
24
Q

What methods can be called for a static class setup?

A

1) Load
2) Initialize

Load gets called when the framework loads the class.
It is called also on categories right after their base classes. Load is not participating in overrides, so each class calls its own load method, and classes without an implementation get left out. Load blocks the runtime.

Initialize is called lazily before a class receives its first message. It uses override and is called also on non-implementing classes, which then call their superclasses implementation. It’s called on the superclasses init first.

Both methods should be used only for tasks that are not possible during runtime, like static array initialization.

25
Q

Provisioning Profile

A

Connects Developer Certificate, 1 App ID and a list of device ID’s that are allowed for that application. It lives on the computer and on the device.

26
Q

ViewController lifecycle

A

[ 0) ‘Initialize’ class, then ‘load’ (when first message call) ]

1) Instantiation:
via storyboard: - awakeFromNib
via code: - initWithNibName: Bundle

2) outlets get set
3) - viewDidLoad (no frame set yet!)

4) (geometry & frame is set, and later whenever geometry changes, zB with device rotation)
- viewWillLayoutSubviews
- viewDidLayoutSubviews

5) - viewWillAppear
(when on screen: self.view.window != nil )
- viewDidAppear

6) - viewWillDisappear
- viewDidDisappear

7) - dealloc
(called just before leaving the heap. All objects will be nil at that time already! Use only for “removeObserver” )

27
Q

ViewController lifecycle

A

0) ‘+load’ called before main(), also called on categories (excellent place to do evil things like method swizzling) ‘+Initialize’ (when first message call, once per class, and if not implemented the superclasses one will be called again! Therefor wrap in if(self == [MyClass class])

1) Instantiation:
via storyboard: - awakeFromNib
via code: - initWithNibName: Bundle

2) outlets get set
3) - viewDidLoad (no frame set yet!)

4) (geometry & frame is set, and later whenever geometry changes, zB with device rotation)
- viewWillLayoutSubviews
- viewDidLayoutSubviews

5) - viewWillAppear
(when on screen: self.view.window != nil )
- viewDidAppear

6) - viewWillDisappear
- viewDidDisappear

7) - dealloc
(called just before leaving the heap. All objects will be nil at that time already! Use only for “removeObserver” )

28
Q

What do you need to implement when using a custom Object as key in a collection?
And how can those methods be implemented for example?

A

NSCopying Protocol, that is on NSObject. This has 2 methods: - isEqual: and -hash.

Using == to compare objects just compares if they have the same memory address.

isEqual compares the value is exactly the same.
typical isEqual example:

-(BOOL)isEqual:(id)object {
if(self == object) return YES;
if([self class] != [object class]) return NO;

MyPerson otherPerson = (MyPerson)object;
if(![self.firstname isEqualToString:otherPerson.firstname]) return NO;

return YES; }

-(NSUInteger) hash {
NSUInteger firstnameHash = [_firstname hash];
NSUInteger lastnameHash = [_lastname hash];
NSUInteger ageHash = _age;
return firstnameHash ^ lastnameHash ^ ageHash; }

=> using XOR because it distributes the bits better than AND or OR.

29
Q

How do you copy an Array?

A

You can do shallow and deep copies.

Shallow copies:

NSArray *shallowCopyArray = [someArray copyWithZone:nil];

NSDictionary *shallowCopyDict = [[NSDictionary alloc] initWithDictionary:someDictionary copyItems:NO];

Deep copies:

NSArray *deepCopyArray=[[NSArray alloc] initWithArray:someArray copyItems:YES];

If you create a deep copy of a collection in this way, each object in the collection is sent a copyWithZone: message. If the objects in the collection have adopted the NSCopying protocol, the objects are deeply copied to the new collection, which is then the sole owner of the copied objects. If the objects do not adopt the NSCopying protocol, attempting to copy them in such a way results in a runtime error. However, copyWithZone: produces a shallow copy. This kind of copy is only capable of producing a one-level-deep copy. If you only need a one-level-deep copy, you can explicitly call

NSArray *deepCopyArray=[[NSArray alloc] initWithArray:someArray copyItems:YES];
This technique applies to the other collections as well. Use the collection’s equivalent of initWithArray:copyItems: with YES as the second parameter.

If you need a true deep copy, such as when you have an array of arrays, you can archive and then unarchive the collection, provided the contents all conform to the NSCoding protocol. An example of this technique is shown in Listing 3:

NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:
[NSKeyedArchiver archivedDataWithRootObject:oldArray]];

Copying and Mutability

When you copy a collection, the mutability of that collection or the objects it contains can be affected. Each method of copying has slightly different effects on the mutability of the objects in a collection of arbitrary depth:

copyWithZone: makes the surface level immutable. All deeper levels have the mutability they previously had.
initWithArray:copyItems: with NO as the second parameter gives the surface level the mutability of the class it is allocated as. All deeper levels have the mutability they previously had.
initWithArray:copyItems: with YES as the second parameter gives the surface level the mutability of the class it is allocated as. The next level is immutable, and all deeper levels have the mutability they previously had.
Archiving and unarchiving the collection leaves the mutability of all levels as it was before.

30
Q

Describe NSMapTable and NSHashTable

A

Both just have a mutable version.

NSMapTable = NSDictionary with options..
NSHashTable = NSSet with options..

Options:

  • can hold weak references
  • can copy values
  • can contain arbitrary pointers, and use pointer identity for equality and hashing checks.

Instances where one might use NSMapTable include non-copyable keys and storing weak references to keyed delegates or another kind of weak object.
NSMapTable *mapTable = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory
valueOptions:NSMapTableWeakMemory];
[mapTable setObject:delegate forKey:@”foo”];

31
Q

Explain retain cycles in blocks and how to solve them!

A

__weak MyObject *weakSelf = self;
[self setMyBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[weakSelf doSomethingWithObj:obj];
}];