@implementation MyClass @synthesize noDeclaredIvar = _noDeclaredIvar; @end “MyClass.h” @interface MyClass : NSObject { float _declaredIvar; } @property float declaredIvar; @end “MyClass.m” @implementation MyClass @synthesize declaredIvar = _declaredIvar; @end legacy runtime modern runtime • iPhone applications and 64-bit programs on OS X v10.5 and later use the modern version of the runtime. • Other programs (32-bit programs on OS X desktop) use the legacy version of the runtime. Monday, 19 November, 12
an instance variable with the same name and compatible type of the property or specify another existing instance variable in the @synthesize statement With the modern runtime, if you do not provide an instance variable, the compiler adds one for you Monday, 19 November, 12
keeping track of objects you own using reference counting Automatic Reference Counting (ARC) uses the same reference counting system as MRR inserts the appropriate memory management method calls at compile-time strongly encourage to use ARC for new projects. Monday, 19 November, 12
use This causes memory corruption, and typically results in your application crashing, or worse, corrupted user data Not freeing data that is no longer in use causes memory leaks Leaks cause your application to use ever- increasing amounts of memory, which in turn may result in poor system performance or your application being terminated Monday, 19 November, 12
Three important words “alloc”, “new”, “copy”. You can take ownership of an object using retain When you no longer need it, you must relinquish ownership of an object using release You must not relinquish ownership of an object you do not own Monday, 19 November, 12
retain count of 1. When you send an object a retain message, its retain count is incremented by 1. When you send an object a release message, its retain count is decremented by 1. If an object’s retain count is reduced to zero, it is deallocated. Monday, 19 November, 12
heap until I don’t point to it anymore” I won’t point to it anymore if I set my pointer to it to nil. Or if I myself am removed from the heap because no one strongly points to me! weak “keep this as long as someone else points to it strongly” Monday, 19 November, 12
when to use retain, release, and autorelease, ARC evaluates the lifetime requirements of your objects and automatically inserts appropriate memory management calls for you at compile time retain => strong assign => weak Monday, 19 November, 12
reference to that object An object cannot be deallocated until all of its strong references are released Retain cycle arise if two objects have a strong reference to each other Monday, 19 November, 12
Page object and the Page object has a strong reference to the Document object, neither object can ever be deallocated The Document’s reference count cannot become zero until the Page object is released, and the Page object won’t be released until the Document object is deallocated Monday, 19 November, 12
to use weak references. A weak reference is a non-owning relationship where the source object does not retain the object to which it has a reference there must be strong references somewhere if there were only weak references, then the pages and paragraphs might not have any owners and so would be deallocated Monday, 19 November, 12
references to its “children,” and the children should have weak references to their parents the document object has a strong reference to (retains) its page objects but the page object has a weak reference to (does not retain) the document object Monday, 19 November, 12
but are not restricted to, table data sources, outline view items, notification observers, and miscellaneous targets and delegates when a delegate object is deallocated, you need to remove the delegate link by sending a setDelegate: message with a nil argument to the other object. These messages are normally sent from the object’s dealloc method Monday, 19 November, 12
{} What does it look like? Here’s an example of calling a method that takes a block as an argument. [aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { NSLog(@“value for key %@ is %@”, key, value); if ([@“ENOUGH” isEqualToString:key]) { *stop = YES; } }]; This NSLog()s every key and value in aDictionary (but stops if the key is ENOUGH). Monday, 19 November, 12
then use it just as you would a function: int multiplier = 7; int (^myBlock)(int) = ^(int num) { return num * multiplier; }; printf("%d", myBlock(3)); / / prints "21" Monday, 19 November, 12
method parameters is that they enable the caller to provide the callback code at the point of invocation Because this code does not have to be implemented in a separate method or function, your implementation code can be simpler and easier to understand Monday, 19 November, 12
block? NSString *stopKey = [@“Enough” uppercaseString]; double stopValue = 53.5; [aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { NSLog(@“value for key %@ is %@”, key, value); if ([stopKey isEqualToString:key] || ([value doubleValue] == stopValue)) { *stop = YES; } }]; stopKey will essentially have a strong pointer to it until the block goes out of scope or the block itself leaves the heap (i.e. no one points strongly to the block anymore). Monday, 19 November, 12
a block Blocks are kind of like “objects” with an unusual syntax for declaring variables that hold them. Usually if we are going to store a block in a variable, we typedef a type for that variable, e.g., typedef double (^unary_operation_t)(double op); This declares a type called “unary_operation_t” for variables which can store a block. Specifically, a block which takes a double as its only argument and returns a double Monday, 19 November, 12
and give it a value ... unary_operation_t square; square = ^(double operand) { return operand * operand; } And then use the variable square like this ... double squareOfFive = square(5.0); We could then use the unary_operation_t to define a method typedef double (^unary_operation_t)(double op); - (void)addUnaryOperation:(NSString *)op whichExecutesBlock:(unary_operation_t)opBlock { [self.unaryOperations setObject:opBlock forKey:op]; } Monday, 19 November, 12
property in a class? @property (nonatomic, strong) NSArray *myBlocks; / / array of blocks And then tried to do the following in one of that class’s methods? [self.myBlocks addObject:^() { [self doSomething]; }]; We said that all objects referenced inside a block will stay in the heap as long as the block does. (in other words, blocks keep a strong pointer to all objects referenced inside of them) In this case, self is an object reference in this block. Thus the block will have a strong pointer to self. But notice that self also has a strong pointer to the block (through its myBlocks property)! (Circular reference) Monday, 19 November, 12
a way to declare that a local variable is weak: __weak MyClass *weakSelf = self; [self.myBlocks addObject:^() { [weakSelf doSomething]; }]; This solves the problem because now the block only has a weak pointer to self. (self still has a strong pointer to the block, but that’s okay) As long as someone in the universe has a strong pointer to this self, the block’s pointer is good. And since the block will not exist if self does not exist (since myBlocks won’t exist) Monday, 19 November, 12
using a block as the comparison method) Notification (when something happens, execute this block) Error handlers (if an error happens while doing this, execute this block) Completion handlers (when you are done doing this, execute this block) Multithreading With Grand Central Dispatch (GCD) API Monday, 19 November, 12
idea is that you have queues of operations The operations are specified using blocks. The system runs operations from queues in separate threads The good thing is that if your operation blocks, only that queue will block Monday, 19 November, 12
void dispatch_queue_retain(dispatch_queue_t); / / keep it in the heap until dispatch_release dispatch_queue_t dispatch_get_main_queue(); Monday, 19 November, 12