Sunday, 24 April 2016

A Possible Solution For [Leetcode 238. Product of Array Except Self]


For those who feels interested to give it a try, the coding puzzle can be found here.

The puzzle is as follows:
Given an array of n integers where n > 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].

And the requirements or challenges are:
1. Solve it without division and in O(n).
2. Solve it with constant space complexity.


The following is the solution that I came up with (in Swift). I thought it was the best because it only loops the array once while all other solutions that I found around the web loops the array at least twice. But it doesn't conform to the second requirement about the space complexity because of the recursive call, unfortunately. 


Besides, for some odd reason, this solution will generate a runtime error when the array holds more than 34892 elements. I can't seem to find any logic issues in the code so far (If you happen to read this article, please do get in touch if you found any issues within the code). Fyi, I'm using Xcode 7.3 which comes with Swift 2.2. Not sure if it is a compiler issue.


Here is the code:
func productExceptSelf(nums: [Int]) -> [Int] {
    func product(inout nums: [Int], _ index: Int_ leftProduct: Int) -> Int {
        let number = nums[index]
            
        if index == nums.count-{
            nums[index] = leftProduct
            return number
        }
        else {
            let rightProduct = product(&nums, index + 1number * leftProduct)
            nums[index] = leftProduct rightProduct
            return rightProduct * number
        }
    }
    
    var numbers = nums
    _ = product(&numbers, 01)
    return numbers
}



Tuesday, 13 January 2015

Custom SegmentedControl In Swift

In this tutorial, we will use a third party framework named SMSegmentView to implement a unique and good looking segmented control for your Swift project. You will also learn how easy it is to expand this framework a little bit. ;)


A Short Introduction Of SMSegmentView

I know many of you may not be interested in the background, so please feel free to skip this part :)

Due to the standard look and the relatively low customisability of UISegmentedControl, the author of SMSegmentView wrote this framework for both developers and designer to make their apps more outstanding, which in another way, might also improve the user experience.

The framework supports both image and text in a single segment. Besides of the traditional horizontal look, it also allows you to arrange your segments in a vertical way. You can change the attributes of the text and segment as well. It is written in Swift and very easy to expand with new features, which is perfect to be used in your next project.

Now let start building something.

Build A Custom SegmentedView

First of all, you will need to find the framework here.

Then, create a new Xcode project with the Single View Application template. Name the project whatever you like, but in this tutorial, let's use SegmentedControlSample. Choose Swift as the language and iPhone as the devices.

Now drag the SMSegmentView folder inside the framework to your project and tick "Copy items if needed". And we are now ready to create our very customised segmented control. Pretty easy, huh? :D

Now let's create a property of the instance of SMSegmentView in ViewController.swift:

var segmentedControl: SMSegmentView!
ViewController.swift: Using the exclamation symbol is to tell the compiler: "Don't worry. I'll assign it a value later".

In viewDidLoad() we initialise the segmentedControl by using its frame:dividerColour:dividerWidth: segmentAppearance: method. Add the following code after super.viewDidLoad():


self.view.backgroundColor = UIColor(white: 0.95, alpha: 1.0)

// 1
let appearance = SMSegmentAppearance()
appearance.segmentOnSelectionColour = UIColor(red: 245.0/255.0, green: 174.0/255.0, blue: 63.0/255.0, alpha: 1.0)
appearance.segmentOffSelectionColour = UIColor.whiteColor()
appearance.titleOnSelectionFont = UIFont.systemFontOfSize(12.0)
appearance.titleOffSelectionFont = UIFont.systemFontOfSize(12.0)

appearance.contentVerticalMargin = 10.0

// 2
let segmentFrame = CGRect(x: self.margin, y: 120.0, width: self.view.frame.size.width - self.margin*2, height: 40.0)
self.segmentView = SMSegmentView(frame: segmentFrame, dividerColour: UIColor(white: 0.95, alpha: 0.3), dividerWidth: 1.0, segmentAppearance: appearance)

// 3
self.segmentedControl.addSegmentWithTitle("Segment 1", onSelectionImage: nil, offSelectionImage: nil)
self.segmentedControl.addSegmentWithTitle("Segment 2", onSelectionImage: nil, offSelectionImage: nil)
self.segmentedControl.addSegmentWithTitle("Segment 3", onSelectionImage: nil, offSelectionImage: nil)

// 4
self.segmentView.addTarget(self, action: #selector(ViewController.selectSegmentInSegmentView(_:)), forControlEvents: .ValueChanged)

self.view.addSubview(self.segmentedControl)
(1) Create an instance of SMSegmentAppearance, where you can specify some UI attributes.

(2) Call the initialiser of SMSegmentView. The parameter segmentAppearance reads the SMSegmentAppearance instance we created in step 1.

(3)We add three segments to our segmentedControler. In this demo, we do not need to assign images to our segment. But in real practice, you can add them if you want.

(4)We set an action to react to UIControlEvents.ValueChanged. After this step, don't forget to add the selector selectSegmentInSegmentView(_:) in the ViewController class:
func selectSegmentInSegmentView(segmentView: SMSegmentView) {
    print("Select segment at index: \(segmentView.selectedSegmentIndex)")

}


Now you can give it a try. If everything goes well, you will see the simulator show this when you select a segment:


Hmm... It looks not too bad, but not as good as it is expected, either :(

Don't worry. We haven't finished, yet.

Add the following code right above you added new segment to the segmentedControl:
self.segmentedControl.layer.borderColor = UIColor(white: 0.9, alpha: 1.0).CGColor
self.segmentedControl.layer.borderWidth = 1.0
As SMSegmentView is a subclass of UIView, we can use UIView's methods to give it a border.


Expanding The Framework A Little...

Now let's expand it a little bit to give it some animation when we select at a segment. First of all, let add another property to our ViewController:
var seletionBar: UIView = UIView()
And add the following code at the bottom of viewDidLoad().
self.seletionBar.frame = CGRect(x: 0.0, y: 0.0, width: self.segmentedControl.frame.size.width/CGFloat(self.segmentedControl.numberOfSegments), height: 5.0)
self.seletionBar.backgroundColor = UIColor(white: 0.5, alpha: 0.6)
You'll know how we are gonna use this view right as follows. Change the SMSegmentView delegate method to:
func segmentView(segmentView: SegmentView didSelectSegmentAtIndex index: Int) {
    
    // 1
    let placeSelectionBar = { () -> () in
        var barFrame = self.seletionBar.frame
        barFrame.origin.x = barFrame.size.width * CGFloat(segmentIndex)
        self.seletionBar.frame = barFrame
    }

    // 2
    if self.seletionBar.superview == nil {
        self.segmentedControl.addSubview(self.seletionBar)
        placeSelectionBar()
    }
    else {
        UIView.animateWithDuration(0.3, animations: {
        placeSelectionBar()
        })
    }
}
(1) We are using a closure to calculate where our bar should be placed.
(2) If no segment has been selected, yet, we will need to add the selectionBar view to our segmentedControl before put the bar on the right place. Otherwise, we animatedly reposition the bar view.

Let's run the app and see how it goes now.



It looks more dynamic now. Pretty easy stuff to make the change, right? ;)


A Little Bit More Words At The End

If you feel sick of the traditional horizontal arrangement of the segments, this framework also provides you a vertical way. All you need to do is to assign its organiseMode with .SegmentOrganiseVertical value after the view gets initialised.

Find the sample comes with the framework and you will know more about it.

Happy Coding :D


Sunday, 18 March 2012

Understanding of 'self' in Objective-C


From: http://useyourloaf.com/blog/2011/2/8/understanding-your-objective-c-self.html
A frequent question I see from people new to iOS programming is why access to an objects instance variables (ivars) sometimes goes via the self object (but not always). For example consider a simple table view controller that contains an NSDate object defined as follows:
@interface RootViewController : UITableViewController {
  NSDate *timestamp;
}
@property (nonatomic, retain) NSDate *timestamp;

The view controller typically then contains code similar to the following:
@implementation RootViewController 
@synthesize timestamp;
- (void)viewDidLoad
{
  [super viewDidLoad];
  self.timestamp = [NSDate date];
}
- (void)viewWillAppear:(BOOL)animated
{
  self.timestamp = [NSDate date];
  [self.tableView reloadData];
}
- (void)viewDidUnload
{
  [super viewDidUnload];
  self.timestamp = nil;
}
- (void)dealloc
{
  [timestamp release];
  [super dealloc];
}
So why does this code use self.timestamp everywhere except the dealloc method? To understand what is going on you need to understand something about Objective 2.0 properties, accessors and the dot syntax. That is quite a big topic in itself so I will to summarise the key points.

Objective-C Properties

The property declaration for the timestamp object is as follows:
@property (nonatomicretainNSDate *timestamp;

The important point to notice is that we have specified retain to indicate that when we set the ivar we should retain the object we are assigning (and of course release any old object we were previously retaining). The implementation of RootViewController includes an @synthesize statement so the compiler will automatically generate getter and setter methods for us that will respect this requirement. Typical getter and setter methods would look like this:
- (NSDate *)timestamp
{
  return timestamp;
}
- (void)setTimestamp:(NSDate *)newValue
{
  if (timestamp != newValue)
  {
    [timestamp release];
    timestamp = [newValue retain];
  }
}

The getter is not interesting since it just returns the value of the ivar. The setter method is more interesting since it needs to practise safe memory management. This means whenever we assign a new object we first release the old object and then ensure we retain the new object so that it does not get deallocated before we are finished with it.
To use the setter to store a new NSDate object in our view controller we could write something like this:
[self setTimestamp:myNewDate];

This is sending the message setTimestamp to the self object where the self object refers to the RootViewController object. This ends up calling our setter method to safely assign and retain the new object. However there is an alternative to this setter method syntax.

Objective-C Dot Syntax

The dot syntax was introduced with Objective-C 2.0 and generates a lot of debate. A number of experienced and long time Cocoa programmers recommend avoiding it completely. Others such as Chris Hanson have a different view about when to use properties and dot notation. Whichever side of the argument you fall I guess the main thing is to be consistent.
Anyway the main thing to understand about the dot syntax is that the following two statements are doing the same thing:
  self.timestamp = [NSDate date];
  [self setTimestamp:[NSDate date]];

The dot is just a shortcut for the more traditional Objective-C method call. Any time you see a dot you can replace it with the equivalent square bracket method call syntax. It is important to understand however that this is not the same as writing the following:
timestamp = [NSDate date];

Without the self object and the dot we are no longer sending an object a message but directly accessing the ivar named timestamp. Since this bypasses the setter method we will overwrite the timestamp ivar without first releasing the old NSDate object. We will also not retain the new object that we are assigning. Both of these situations are bad!

Putting it all together

If we walk through each of the view controller methods we saw at the start of this post it should now be clear why each access to timestamp is written the way it is:
Firstly the viewDidLoad and viewWillAppear methods both allocate a new date object and need to store a reference to this new object in the ivar of the view controller. Since we may already have an existing object allocated this first needs to be released before assigning the new value. In other words we need the setter method which we can invoke using the timestamp property:
self.timestamp = [NSDate date];
If we were to omit the self object in the first of those two statements (timestamp = [NSDate date];) we would be accessing the ivar directly which bypasses the setter and ends up leaking memory.
The viewDidUnload method is somewhat different in that it uses a shortcut to both release the NSDate object and then zero the ivar. If you refer back to the setter method you will see that it takes care of the release for us. This is of course true as long as we use the property, if we access the ivar directly we would need to also release the object as follows:
  [timestamp release];
  timestamp = nil;

which is somewhat longer than simply writing this:
   self.timestamp = nil;

Finally the dealloc method which simply releases the NSDate object needs to access the ivar directly which is what [timestamp release] does.

Separating ivars from properties

There is a further option that I think is also worth mentioning at this point. By default when you synthesize the getter and setter accessor methods it is assumed that the property and ivar have the same name. This can make it confusing at first glance as to when you are using the getter/setter methods and when you are accessing the ivar directly. The alternative is name the ivar differently from the property. A common approach is to use an underscore to prefix the ivars names:
@interface RootViewController : UITableViewController {
    NSDate *_timestamp;
}
@property (nonatomic, retain) NSDate *timestamp;

To connect the property (whose name has not changed) the sythensize statement gets an extra option:
@implementation RootViewController

@synthesize timestamp = _timestamp;

If instead of having the compiler automatically synthesize the getter and setter we were to write them ourselves they would now look something like this:
- (NSDate *)timestamp
{
    return _timestamp;
}
- (void)setTimestamp:(NSDate *)newValue
{
    if (_timestamp != newValue)
    {
        [_timestamp release];
        _timestamp = [newValue retain];
    }
}
The getter and setter both directly access the ivar which is now much clearer from the use of the _timestamp name. The rest of the code does not change very much since we do mostly want to always use the getter/setter methods with the exception of the dealloc method which needs to access the ivar directly:
- (void)dealloc
{
    [_timestamp release];
    [super dealloc];
}

The main advantage to this approach is if you forget and accidentally write something like this:
    timestamp = [NSDate date];

This will generate a compiler error telling you that timestamp is undeclared. This is clearly better than directly assigning to the ivar and leaking memory. What I like about this approach is that it provides some additional compile time checking without requiring much in the way of additional code other than a slightly longer synthesize statement for each property.

Monday, 14 November 2011

UIWebView and EXC_BAD_ACCESS

When using a UIWebView, if it is released before loading the full content, an EXC_BAD_ACCESS will be aroused. The following article gives a solution to the problem.

From: http://www.touch-code-magazine.com/uiwebview-and-exc_bad_access/

It is great that in Cocoa Touch you can embed a UIWebView in your app and show web content. It’s basically the same view which safari uses to render web pages, so you get years of web rendering development for free.

UIWebViewDelegate

If you want to use UIWebView the first thing to do is have a look at UIWebViewDelegate protocol:

@protocol UIWebViewDelegate 
 
@optional
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
- (void)webViewDidStartLoad:(UIWebView *)webView;
- (void)webViewDidFinishLoad:(UIWebView *)webView;
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;
 
@end
Quite straightforward to use : you set your viewcontroller (or any other object) to be the delegate for the UIWebView and you can optionally implement
  • shouldStartLoadWithRequest – you can check the NSURLRequest to see which is the url being request, what parameters, etc. This one is useful to actually check the links the user is clicking inside a page. For example if the user has clicked a link “javascript:window.close()” it does not make sense to execute it inside the UIWebView, but you can react in some other way in your app UI
  • webViewDidStartLoad – an HTTP request has been started – great place/time to show an activity indicator
  • webViewDidFinishLoad – a page has been loaded (including all resources like images, etc) – that’s a great moment to hide your activity indicator
  • didFailLoadWithError – error handling


Threading and EXC_BAD_ACCESS

As you can imagine there are several layers of workers in a component as complicated as a web browser – even if you don’t see everything happening behind the curtain – it’s all there, html needs to be parsed, images need to be loaded, css to be applied, etc. etc.
Apple lets you set your UIWebView delegate and be notified when all the work has been done, but if you have some UIWebView controllers inside a navigation controller 0r just more complicated UI you can bump into some sporadic EXC_BAD_ACCESS errors.
The delegate property of UIWebView is non- owning, i.e. it has the assign accessor, thus when the working thread is finished to load all html, css, images, etc. is sends the webViewDidFinishLoad message to the whatever it finds in the delegate property, but it has no way to tell whether the delegate hasn’t been released yet. There you go, if your delegate has been already released (for example you went away from the screen where the web page was supposed to be displayed) – you get a message sent to a released object.
The solution is to set UIWebView’s delegate to nil. The webViewDidFinishLoad message is still sent to it, but since you can send messages to nil it’s actually no problem.
For example in your ViewController class :

- (void)dealloc {
 //very important
 webView.delegate = nil;
 [super dealloc];
}
That’s it.