Monday, 31 August 2015

Autorelease Pool Blocks

Autorelease pool is an object (instance of NSAutorelease class) which will be created at the starting of thread run loop and released at the end of run loop.

When you call autorelease on any object that object will be added to autorelease pool and finally when pool is getting released all the objects in the pool will be released. The main purpose of autorelease is to release the object some time later(at end of run loop) but not immediately.

Three occasions when you might use your own autorelease pool blocks.
  • If you are writing a program that is not based on a UI framework, such as a command-line tool. 
  • If you write a loop that creates many temporary objects. You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application. 
  • If you spawn a secondary thread.
NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {

    @autoreleasepool {
        NSError *error;
        NSString *fileContents = [NSString stringWithContentsOfURL:url
                                         encoding:NSUTF8StringEncoding error:&error];
        /* Process the string, creating and autoreleasing more objects. */
    }
}
Documentation

Sunday, 30 August 2015

NSThread vs GCD vs NSOperationQueue


Use NSThread (or even the pthreads API) when you want or need to have direct control over the threads you create, e.g. you need fine-grained control over thread priorities or are interfacing with some other subsystem that vends/consumes thread objects directly and you need to stay on the same page with it. Such instances are rare, but they do occur, particularly in real-time applications.

Use GCD when your task lends itself well to simple parallelization, e.g. you just want to toss some work "into the background" with very little additional work, you have some data structures that you merely wish to serialize access to (and serial queues are great for doing that in a lockless fashion), you have some for loops that would lend themselves well to parallelization with dispatch_apply(), you have some data sources / timers that GCD's sources API will enable you to deal with easily in the background, etc etc. GCD is quite powerful and you can use it for a lot more than this, but these are all relative 'no brainer' scenarios where you don't want to get caught up in the initialization and setup tasks so much as simply "do basic stuff in parallel".

Use NSOperation when you're already up at the Cocoa API layer (vs writing in straight C to the POSIX APIs) and have more complex operations you want to parallelize. NSOperation allows for subclassing, arbitrarily complex dependency graphs, cancellation and a supports a number of other higher-level semantics that may be useful to you. NSOperation actually uses GCD under the covers so it's every bit as multi-core, multi-thread capable as GCD, though it also brings the Foundation framework along for the ride so if you're hacking at the POSIX layer, you probably want to use option #2.

SO link

Thread Management
  • Threading has a real cost to your program (and the system) in terms of memory use and performance. Each thread requires the allocation of memory in both the kernel memory space and your program’s memory space.
  • NSOperationQueue is objective C wrapper over GCD, so when you want more control over queue use that and for simple cases (where you want less overhead) use GCD
  • In iOS and OS X v10.5 and later, all objects have the ability to spawn a new thread and use it to execute one of their methods.
  • [myObj performSelectorInBackground:@selector(doSomething) withObject:nil];
  • An operation object is a single-shot object—that is, it executes its task once and cannot be used to execute it again. You typically execute operations by adding them to an operation queue.
  • An operation queue executes its operations either directly, by running them on secondary threads, or indirectly using the libdispatch library (also known as Grand Central Dispatch)
  • you can execute an operation yourself by calling its startmethod directly from your code. Executing operations manually does put more of a burden on your code, because starting an operation that is not in the ready state triggers an exception. The ready property reports on the operation’s readiness
  • When you add an operation to an operation queue, the queue ignores the value of the asynchronous property and always calls the start method from a separate thread. Therefore, if you always run operations by adding them to an operation queue, there is no reason to make them asynchronous
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
        //this block runs on a background thread; Do heavy operation here


        dispatch_async(dispatch_get_main_queue(), ^{
            //This block runs on main thread, so update UI

        }); 
    });





Thursday, 20 August 2015

Detect programmatically when top view controller is popped

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    if (self.isMovingToParentViewController == NO)
    {
        // we're already on the navigation stack
        // another controller must have been popped off
    }
}

Saturday, 8 August 2015

Index path for custom button action inside UItableViewCell

-(void)customeButtonActionFromTableViewCell:(UIButton*) sender
{

CGPoint touchPoint = [sender convertPoint:CGPointZero toView:urTableView]; 
NSIndexPath *clickedButtonIndexPath = [urTableView indexPathForRowAtPoint:touchPoint];
 }

Thursday, 6 August 2015

Keyboard height change handling.

in viewDidLoad
[[NSNotificationCenter defaultCenter]
         addObserver:self
         selector:@selector(keyboardWasShown:)
         name:UIKeyboardWillShowNotification
         object:nil];

        [[NSNotificationCenter defaultCenter]
         addObserver:self
         selector:@selector(keyboardWillBeHidden:)
         name:UIKeyboardWillHideNotification
         object:nil];
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification *)aNotification {

    [self scrollControlBarTo:aNotification up:YES];

}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification *)aNotification {


     [self scrollControlBarTo:aNotification up:NO];

}


- (void)scrollControlBarTo:(NSNotification *)notification up:(BOOL)up
{

    CGRect keyboardBounds;
    NSDictionary *info = [notification userInfo];
    NSNumber *number = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    double duration = [number doubleValue];
    [[info objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardBounds];
    [UIView animateWithDuration:duration
                          delay:0
                        options:UIViewAnimationOptionCurveLinear
                     animations:^{
                         containerBottom.constant = (up) ? 8+keyboardBounds.size.height : 8;
                         [self.view layoutIfNeeded];
                     } completion:nil];
}