Tuesday, July 26, 2011

Difference between Copy and MutableCopy


The difference between 'copy' and 'mutableCopy' can be simply understood with polymorphism in Object Oriented Programming concepts.

We will take the example of Array in objective-C. MutableArray is the extension of NSArray class. Therefore, all the methods available in NSArray is available in NSMutableArray, but the additional methods present in NSMutableArray is not known to NSArray class.

Now moving ahead, the copy method on an NSArray will return an object of type NSArray(The array that can not be modified). And mutableCopy method will return an object of mutable type (The array that can be modified).

Now, there can below cases :

Case 1:

    NSArray *arr1=[NSArray arrayWithObjects:@"A",@"B",@"C", nil];
    NSArray *arr2=[arr1 copy];

    NSLog(@"arr1:%@",[arr1 description]);
    NSLog(@"arr2:%@",[arr2 description]);

In this case an NSArray object is returned and is received in an NSArray object.
So, the array received can not be modified.

Therefore, we will not be able to use below statement
[arr2 insertObject:@"Z" atIndex:0];


Case 2:

    NSArray *arr1=[NSArray arrayWithObjects:@"A",@"B",@"C", nil];
    NSArray *arr2=[arr1 mutableCopy];

    NSLog(@"arr1:%@",[arr1 description]);
    NSLog(@"arr2:%@",[arr2 description]);

In this case an NSMutableArray object is returned and is received in an NSArray object.
Since the receiver object is of type NSArray, it doesn't know the methods present in NSMutableArray, arr2 will not be able to use any of the methods of NSMutableArray.
That is, the method mutableArray will make no sense in this scenario.

So, we will not be able to use below statement
[arr2 insertObject:@"Z" atIndex:0];

Case 3:

    NSArray *arr1=[NSArray arrayWithObjects:@"A",@"B",@"C", nil];
    NSMutableArray *arr2=[arr1 copy];

    NSLog(@"arr1:%@",[arr1 description]);
    NSLog(@"arr2:%@",[arr2 description]);

In this case an NSArray object is returned and is received in an NSMutableArray type object. The receiver arr2 is now pointing to an object address that is of type NSArray. However arr2 has the additional methods than NSArray, it will not be able to use those methods coz the pointed object NSArray does not know the additional methods present in arr2(NSMutableArray).

Hence, we will not be able to use below statement
[arr2 insertObject:@"Z" atIndex:0];


Case 4:

    NSArray *arr1=[NSArray arrayWithObjects:@"A",@"B",@"C", nil];
    NSMutableArray *arr2=[arr1 mutableCopy];

    NSLog(@"arr1:%@",[arr1 description]);
    NSLog(@"arr2:%@",[arr2 description]);
    [arr2 insertObject:@"Z" atIndex:0];

In this scenario, the receiver(arr2) of type NSMutableArray receives an object of type NSMutableArray. Therefore, the receiver knows the additional methods of NSMutableArray as well as the object that is being pointed by receiver(arr2).

And finally below statement will work like charm,
[arr2 insertObject:@"Z" atIndex:0];

Log before insertion will be:
arr1:(
    A,
    B,
    C
)
arr2:(
    A,
    B,
    C
)
And log after insertion will be:
arr1:(
    A,
    B,
    C
)
arr2:(
    Z,
    A,
    B,
    C
)



Hope above description helped you.


Saturday, July 23, 2011

Random questions in iOS

1) How to disable UIWebView scrolling ?

Ans: UIWebView is derived from UIScrollView. Therefor we must be able to disable the scrolling of UIWebView.

Here is the working code:
UIScrollView *scrollView=[[webView subViewslastObject];
[scrollView setScrollingEnabled: NO];

2) How to check the iOS version of device ?

Ans: This is a very frequent scenario where you need to check which version of iOS the target device is running.

The very best solution that Apple recommends is,

  • if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
  • // Load resources for iOS 6.1 or earlier
  • } else {
  • // Load resources for iOS 7 or later
  • }

Tuesday, July 12, 2011

Blank status bar problem with MediaPlayer


Playing videos in iOS is like butter and nothing much on developer side.

iOS has provided MediaPlayer.framework to play videos either from resource or from a http url.

In a full screen application development, you might come across the problem that, after finish of the video play the status bar is hidden and the place for status bar is left blank (white).

Also, this problem may occur when you present the MoviePlayerViewController on current view and not on adding MoviePlayerViewController's view on the parent view
i.e,
[self presentMoviePlayerViewControllerAnimated:moviePlayerViewController];
not on doing
[self.view addSubview:[[moviePlayerViewController moviePlayer] view]];

Hey, and do not forget to test your code on iPad device, as you can find this problem only on device & works fine on simulator.


You will notice that the status bar is left blank when you click on "Done" button while video is being played. If the video ends after full video play everything goes right.

This white status bar may look like this:



To handle this problem, We add observers for MPMoviePlayer class notifications and all you need is to set the status bar hidden in the method implementation of 'MPMoviePlayerPlaybackDidFinishNotification' notification, as below:

We can add MoviePlayer notification observers as below:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_MPMoviePlayerPlaybackDidFinishNotification) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];

The implementation for 'MPMoviePlayerPlaybackDidFinishNotification' can be as below:

-(void)_MPMoviePlayerPlaybackDidFinishNotification{
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];

}

That is all we need to do.
You can download the working code here