December 22, 2011

Excerpt from "the netscape dorm"

   
All of the paragraphs below are excerpted from "the netscape dorm". It is a joyful experience reading the diary. But maybe this is just as what Jamie Zawinski said: "This is the time period that is traditionally referred to as "the good old days,'' but time always softens the pain and makes things look like more fun than they really were. But who said everything has to be fun? Pain builds character. (Sometimes it builds products, too.) ".

======================

But it was no big deal, we just had the meeting later. It's hard for someone to hold it against you when you miss a meeting because you've been at work so long that you've passed out from exhaustion.

Wow, I must be tired -- I just turned on the television, and MTV is actually moving too fast for me to understand it.

I saw Ian today, for the first time in months. His first words were, ``Wow, you look like shit.'' He says I seem really strung-out and twitchy. I thought I had been doing ok! I got a full night's sleep last night and everything. I have no life. I never see any of my non-work friends, and I'm wasting away my one and only youth. I ought to be out doing fun things and active things, the kind of things I won't be able to do when my mind and body finally decay. But instead I'm stuck inside under fluorescent lights, pushing bits around inside a computer in ways that are only interesting to other nerds. I glanced at a movie listing and there are movies out that I haven't even heard of. How did that happen? That freaks me out.

I've just read over some of my diary for the last few months, and man, a lot of it is completely incoherent! It's full of incomplete sentences, made up words, random surreal imagery that I can't even understand let alone remember typing. Have I been typing in my sleep? I hope I don't sound like that in person. I wonder what my code must look like! Oh well, it seems to work.

Well today has been more than a little bit frustrating. The details don't really matter (what does!), but I've spent most of the day so stressed out that my skull is rattling from the pressure of my teeth grinding together. I feel like I have finally exceeded my stress limits and am about blow a gasket. But I can't go home, because if I do, the world will end, right? I'm trying to work, but every few minutes I have to stop typing and make fists so tightly that my whole body shakes.

Coots know how to live. I wish I were a coot. Mr. Wizard, I think I'd rather be a coot than a hacker. Yeah, sure, every now and then a giant pink-haired ape would come running after me and chase me into the lake, but really, could it be that much worse? I'd have a tiny little brain and wouldn't be expected to worry about anything.

The power came back on, and we put the damnable program on the FTP server, and two million people all started attempting to download it at once, before we had even posted the announcement message, and we're done done done and I suppose now we can all live happily ever after…… We sat in the conference room and hooked up the big TV to one of the Indys, so that we could sit around in the dark and watch the FTP download logs scroll by. jg hacked up an impromptu script that played the sound of a cannon shot each time a download successfully completed. We sat in the dark and cheered, listening to the explosions.

I've just noticed that there's still purple ink on the inside of my right wrist spelling the word VOID: the hand-stamp from a concert that I went to last week. I left work, went to the show, and came back to work immediately afterwards. I've been here since.

December 19, 2011

Memory Management in Obj C

                                
I just complete my 2nd iOS homework, which took me cumulative 40 hours. The part that impressed (or... baffled...) me most is about dealing with memory management. In one scree, I opened the Xcode IDE, and in another screen, I just cross-referenced StackOverflow, Developer Library, and Google searching over and over again. There was no one-stop solution for all of the problems I met. But it only made me feel more enjoyable when I finally found the path to solution:) In case that I might forget the key points all I have collected, I record them here with references.

1. Declaration of object.
MyObject* myObject;
WRONG! This means myObject points to a chunk of garbage memory, which would not correctly work at all. Basically, there are two ways to do this correctly:
MyObject* myObject=nil;
MyObject* myObject=[[MyObject alloc] init]; 

The former one makes myObject to point to nothing. Now it at least consistently does nothing, or I could use this pointer points to some useful object later on. But this will also lends to another issue about the life-cycle of a object which I will talk about in detail later. The latter one is to allocate a MyObject object in the memory, initialize it, and then make myObject point to the chunk of memory correctly allocated and initialized. Now, if the MyObject has the interface
@interface MyObject:NSObject{
    NSString* string;
}

@end

@implementation MyObject
-(id) init {
      if(self=[super init]){
           ...do something ...
     }
      return self;
}

after [super init] is successfully performed, Objective-C guarantees that the ivar string is set to nil, i.e. string points to nothing. But it is not that an NSString is allocated or initialized.

2. Basic rules about ownership  and memory management:
  • Any object returned by alloc, copy, copyWithZone, or new has a retain count of 1.
  • retain increases the receiving object's retain count.
  • release decreases the receiving object's retain count.
  • autorelease tells the current autorelease pool to send the receiving object the release message “later”.
  • Any factory method that doesn't have “new” or “copy” in the name (e.g., stringWithString:) returns an object that it has autoreleased on your behalf.
  • Conversely, if you are not the creator of an object and have not expressed an ownership interest, you must not release it.
Or, digested a bit:
  • Any method whose name contains copy, alloc, retain, or new returns an object that you own.
  • Any method that doesn't, returns an object that you don't own.
  • To own an object, retain it.

Reference: StackOverflow, Developer Library. An example about retain and release, and another deeper discussion.

3. copy versus retain

There are lots of discussions about the subtle differences between these two operations, though they both intend to take the ownership from the acquired objects. "(Almost) every time you use retain in Objective-C/Cocoa, you really should be using copy. Using retain can introduce some subtle bugs, and copy is faster then you think…" The problem with using retain to “take ownership” of an object is that someone else has a pointer to the same object, and if they change it, you will be affected.

There are some other discussions concerning the same kind of problem in StackOverflow and post in a blog. Besides, I also made to rookie mistakes that took me quite a while to find out and correct.

4. Has a @synthesize property already init & alloc-ed?

The answer is NO. It needs to populate the property manually. The exception is if you have an IBOutlet property that you've connected in a nib file; that will get populated automatically when the nib is loaded.

For view controllers, the vast majority of properties are IBOutlets and properties that describe what the view will show, and the latter case is usually set by the object that creates the view controller. That will usually be the case for a view controller that shows a detail view for some object.

If you do have properties that are completely local to the view controller, a common pattern is to write your own getter and setter (rather than using @synthesize) and create the object in the getter if it doesn't exist. This lazy-loading behavior means you can easily free up resources in low-memory conditions, and that you only pay the cost of loading an object when you need it.
// simple lazy-loading getter
- (MyPropertyClass*) propertyName {
    if(propertyIvarName == nil) {
        propertyIvarName = [[MyPropertyClass alloc] init];
        ......  // ... other setup here
    }
    return propertyIvarName;
}


5. Pitfall about the use of getter/setter:
@interface MyObject:NSObject{
    NSString *aString;
}
@property (nonatomic, copy) NSString *aString;
- (void) someMethod;
@end

@ implementation MyObject {
@synthesize aString;
- (id) init {
    ......
}
- (void) someMethod {
    ......
    aString = [NSString stringWithString: @"blah, blah, blah."];
    aString = [[NSString stringWithString: @"blah, blah, blah."] retain];
    aString = [[NSString stringWithString: @"blah, blah, blah."] copy];
    self.aString = [NSString stringWithString: @"blah, blah, blah."];
    ......
}

The compiler would not pop up any warning or error about the code above. But the 1st line in the method is extremely dangerous as well as a bug hard to find: the aString does not own the returned object, which will be released at some time after the method is completed. Corresponding to the second factor that I write above, it is obvious that this sentence has no keywords about ownership. Worse still, although the ownership is considered in the @property, this sentence does not call the setter method. The right way to activate the setter is the 4th sentence. Besides, the 2nd and 3rd sentence request the ownership of the new object in another form. They are legal, of course.

[ UPDATE:

6. viewDidUnload vs. dealloc

Unless the program needs to break a retain cycle, it should generally only be releasing objects in the dealloc method. viewDidUnload is an exception; it is invoked in low memory situations and should be used to release anything useless. Then, a preferable way to do this is to write another releaseMemory function where takes most or all of the used objects into consideration and sets them into nil, and then to call this function both in viewDidUnload and dealloc.

The general principle is just as mentioned above: if you do need to release them anywhere else, then always set the reference to nil after the release. That will protect the app from blowing up later (likely in dealloc).

References: StackOverFlow-1, StackOverFlow-2.
]

It is glad that I have gone this far. And, I will move on,  and dig deeper.

cheers.

December 7, 2011

Winter vacation resolution

1. Study at least one online theoretical course;
2. Complete implementation of personal website and the Cal app in iOS;
3. Write blogs frequently documenting the progress;
4. Find a nice com to do the Spring intern;
5. Update info with Dr. Barber every other week about Identity threats;
6. Contact with professors on a daily basis;
7. Cumulate the training hours surpass 2400.

December 3, 2011

不碰你!

哪儿都不能碰!

October 6, 2011

September 27, 2011

Find the longest chain under 1M with Collatz Conjecture condition

It is the #14 problem in Project Euler.
In general, the Collatz conjecture has two main properties:
1. no infinite trajectory occurs;
2. no cycle occurs.

The basic algorithm is quite straightforward. It just follows the instruction of Collatz Conjecture, which are n = n/2 if n is even, and n = 3*n+1 if n is odd. To accelerate the calculation, I also implemented a hash map, which could be retrieve theoretically in constant time O(1), and use the iteration number as the key in this map and the overall steps towards 1 as the value of that key. Under this situation, whenever a new node is found, it will be added into the map, and continue the computation until it reaches some key which has already stored in the map. That is, the route is undetermined before the calculation, but every number only needs to calculate once.

The first problem I met is exactly the problem "Why am I getting an OutOfMemoryError trouble in Java?" described in the StackOverflow. When the program reaches 113383, all of the heap space will be consumed. As I looked up in the internet, all solutions point to how to increase the heap space for Java. While, as I narrowed down the bug to the innermost loop and print out every relevant variable, the bug finally turned out to be the overflow of integer data type. Just change it into long would solve this problem.

The second problem had the same symptom but with a much bigger number. When I print out every variable this time, nothing seemed wrong. But if we check the memory usage in run-time, all of the memory had been consumed by the hash map as some number will have extremely long chain towards 1, part of which are far beyond the range of 1000000. The scale is over 1.5 million items in hash map to achieve 725343. The solution is that the program only record number under 1 million, which are within the searching range and also most likely to be hit.


Solution discussions: [1] (discussion in StackOverflow), [2] (in JavaScript), [3] (optimization), [4] (in C++), [5] (in Python). By the way, here is the discussion about looking up memory usage during run time in Java--it helps me find the 2nd bug. Finally, my solution is in one of my Github repositories.

Days of our lives

Daisypath Anniversary tickers