Sunday, June 28, 2015

A secret tip about modifying Auto layout constraints in Interface Builder

If you make a constraint in Interface Builder.  If you click a constraint that has already be selected.  Normally you would be able to see the knobs for it in the Right panel.  However, if you double click this constraint, a little window will open up that will also let you turn the knows.  Good for if you don't want to open the Right panel.

Also if you press option when a view is selected it will show you the distance from its neighboring views.  Yes, I realized that it isn't Auto layout per se, but it its somewhat related.

Tuesday, June 23, 2015

Objective -c Tuple


Objective - c does not have native support for Tuples.  However, in most cases an NSArray will suffice.  The difference between a tuple and an array is mostly one of categorization.  Tuples are for bundling things that don't have uniformity while Arrays are expected to have the same type.  With that said, a Tuple can be implemented by using an Array, but with it's array features hidden away.

Below is my implantation for a Tuple by using Blocks and variadic function.

typedef id(^TupleType)(NSInteger);
TupleType Tuple(id obj, ...) NS_REQUIRES_NIL_TERMINATION;
TupleType Tuple(id obj, ...) {
va_list argList;
va_start(argList, obj);
NSMutableArray *mut = [NSMutableArray new];
for (; obj; obj = va_arg(argList, id)){
[mut addObject:obj];
}
va_end(argList);
return ^(NSInteger index){
return index >= mut.count ? nil : mut[index];
};
}

You can use it like this

TupleType t = Tuple([MYObj new], [MYObj new], [MYObj new], nil);
for (int i = 0; i < 3; ++i) 
{
NSLog(@"%@", t(i));
}

Sunday, June 21, 2015

Adding a radial gradient

Have you used UIAlertController?  Have you ever made your own?  Well, I have.  This blog will not be able how to make your own UIAlertController; instead, it will be about a little known detail that makes the UIAlertController look the way it does.

If you open up a UIAlertView (the predecessor to UIAlertController) in the View Debugging while you run your app, it will not appear.  Therefore use UIAlertController and it will appear.  Did you know that UIAlertControllers have a radial gradient above it?  It is difficult to tell since the view debugging does NOT reveal this gradient.  Instead it just says that the UIAlertController is White.  But it is more than that.  It is partially transparent and there is a Radial gradient which makes it look like there is a spot light on it.  Very subtle yes I know.

But how do you do that?  How do you make the radial gradient?  The secret word is CGContextDrawRadialGradient

Take a look at my github project and see how I have used it with IBDesignables and IBInspectables.  I used the IBInspectables to learn what each value of CGContextDrawRadialGradient actually does and ran it through IBDesignables to render it as I modify the values.

Friday, June 19, 2015

Codillity Tape equilibrium Solution in Python

The intuitive thing to do is to sum up the array ranges to calculate P of 1..N but that is inefficient.

Observations:
p0 = | (A[0]) - (A[1] + A[2]) |
p1 = | (A[0] + A[1]) - (A[2]) |

If we abstract a bit then we can put the sums into two sets.  The left set can be sum1 and the right set can be sum2.  For each p we essentially add on to set 1 and subtract from set2 the same number.  This saves you from having to sum the array ranges more than you need to.

#solution in Python
import sys
def solution(A):
    sum1 = 0
    sum2 = sum(A)
    diff = sys.maxint
 
    for i in range(0, len(A) -1):
        sum1 += A[i]
        sum2 -= A[i]
     
        _diff = abs(sum1 - sum2)
        if (diff > _diff):
            diff = _diff
    return diff


https://codility.com/demo/results/demo73W5DE-WZP/

Sunday, June 14, 2015

C arrays and Objective-C ARC

I just converted a MRR (manual retain release) project into a ARC (automatic reference counting) project.

I use Xcode to help me convert the project super fast.  However, I noticed that in some of my classes there were C arrays that contained NSObject instances.  My first reaction was to say that C can not manage NSObjects, I mean how?  It isn't like NSArray where if you deallocate the NSArray it would automatically remove its reference from each of its instance.  A C array is a different beast and I could not fathom how it could "remove its reference".

So I skip it and told code to make that particular class MRR.

But curiosity got the best of me and I made a small project to see if the C array of NSObjects would deallocate with its parent class.  In short?  Yes.  The C array deallocates along with its Parent.

Here is the code that I used to test this.

@interface DHView : UIView

@end

@implementation DHView

- (void)dealloc {
NSLog(@"Dealloc: %@", self);
}

@end

@implementation dh123 {
DHView *views[3];
}

-(void)viewDidLoad {
[super viewDidLoad];
views[0] = [DHView new];
views[1] = [DHView new];
views[2] = [DHView new];
for (int i = 0; i < 3; ++i) {
NSLog(@"Create:  %@\n", views[i]);
}
}


@end


 In the viewDidLoad method of dh123ViewController, I create 3 DHViews and add it to the views property.  In the DHView I added an NSLog to the dealloc method so that I could see when it gets deallocated.  When I dismiss dh123ViewController all three DHViews deallocate.

Therefore, you should use as many C array's as your heart desires!

Sunday, May 31, 2015

How to Curry Functions in Objective-C

Calling a function is an all-or-nothing ordeal; You either call it or you don't.  There is no in-between.  Or is there?

In functional programming there is a concept of currying, which mean that you can partially apply a function.  If you have 3 arguments, you can partially apply it by using only the first argument.  The function would then return a partial function.  It is only after applying the 2nd and 3rd arguments will you get the a complete return value.

This is not nearly syntactic sugar.  You can pass around this partial function.  It saves on code duplication.  See the below example to see a C function as a curried function.

    typedef NSDictionary *typeA;
    typedef int typeB;
    typedef float typeC;
    typedef NSArray *typeD;
    typedef NSString *typeE;

    typeE(^(^(^day(typeA A))(typeB B))(typeC C))(typeD D) {
        return ^(typeB B) {
            return ^(typeC C) {
                return ^(typeD D) {
                    return (typeE)[NSString stringWithFormat:@"%@ %d %f %@", A, B, C, D];
                };
            };
        };
    }
...
NSLog(@"%@", day(@{})(99)(215.9)(@[@"bye", @"vanishment"]));  // Example usage

    typeE(^(^(^arg1)(typeB))(typeC))(typeD) = day(@{@"å" : @5});
    typeE(^(^arg2)(typeC))(typeD) = day(@{@"å" : @5})(256);
    typeE(^arg3)(typeD) = day(@{@"å" : @5})(256)(3.14);
    typeE arg4 = day(@{@"å" : @5})(256)(3.14)(@[@76]);
    
    NSLog(@"%p", day);
    NSLog(@"%@", arg1);
    NSLog(@"%@", arg2);
    NSLog(@"%@", arg3);

    NSLog(@"%@", arg4);

2015-05-31 11:03:32.694 curry[2566:41971] 0x10a1bfa40
2015-05-31 11:03:32.696 curry[2566:41971] <__NSMallocBlock__: 0x7fa158c1ce60>
2015-05-31 11:03:32.696 curry[2566:41971] <__NSMallocBlock__: 0x7fa158c5e990>
2015-05-31 11:03:32.696 curry[2566:41971] <__NSMallocBlock__: 0x7fa158c13cf0>
2015-05-31 11:03:32.697 curry[2566:41971] {
    "\U00e5" = 5;
} 256 3.140000 (
    76
)

The above is how you can curry a four argument function that returns a value of typeE.

The return type for the day function may look confusing, but its pattern is essentially just repeated over and over again.  Conceivably you could create a macro or work some typedef magic.  Nonetheless, the partial function works by returning blocks.

Here is another example where I use an objective-c method.  I don't recommend it.

    typedef int type1;
    typedef float type2;
    typedef NSArray *type3;
    typedef NSString *type4;

    - (type4(^(^)(type2))(type3))day:(type1)day {
        return ^(type2 deg) {
            return ^(type3 arr) {
                return (type4)[NSString stringWithFormat:@"%d %f %@", day, deg, arr];
            };
        };
    }

Before we end this i'd like to address the issue of type.  Especially if you try to save the partial function into a variable.  You can not cast it to type id.  I mean you could, but you won't be able to call the parameters.  You could however use "typeof()" to get the type.  It does not appear to call the function twice so you are probably safe from calling something twice.