http://fi.am/entry/ending-misconceptions-about-the-designated-initial/
Category Archives: Development
Image preview for iOS
Ever wanted to have a simple way of previewing an image on iPhone ?
Maybe you have a thumbnail you wish to preview in a larger size ? Or you have a thumbnail downloaded from a url, and if you tap on the thumbnail you want to download the bigger version of the image and preview it ?
Well, you can do all this with this small component. ( download the code at the end of this article )
Let’s see what can you do with this component. In its simplest form, we can use the component to preview a UIImageView’s image:
INImagePreview *preview = [[INImagePreview alloc] init];
[preview previewImage:oneImageView.image parentView:mainView];
[preview release];
In this case we have a UIImageView named oneImageView. We are going to preview the image of this oneImageView. The mainView is going to hold the preview of the image. It looks like this:
The second – and maybe a more useful case is when we tap on a UIImageView but we want to download the bigger version of the thumbnail and display it. This can be achieved with something similar to this:
INImagePreview *preview = [[INImagePreview alloc] init];
[preview previewImageWithUrl:[NSURL URLWithString:@"http://moszi.net/dev/Home_files/server.jpg"]
parentView:mainView];
[preview release];
In this case INImagePreview will show a small UIActivityIndicator until the image is downloaded, then will show the downloaded image.
While this functionality is okay, probably what every developer would do as a next step is to add a UIButton or a UIControl on top of the UIImageView and invoke the code above to preview an image. This is why the next two category methods will be at hand:
[oneImageView previewImageWhenTouchedUpInsideUsingParentView:mainView];
[oneImageView previewUrlWhenTouchedUpInside:[NSURL URLWithString:
@"http://moszi.net/dev/Home_files/server.jpg"] usingParentView:mainView];
The two UIImageView category methods will add functionality to the UIImageView so that when it’s tapped the appropriate image is previewed. The above category methods use Associative Storage (objc_setAssociatedObject) to add an INImagePreview instance to the UIImageView so the functionality can be executed later in time.
You can download the demo project attached to this article. If you like the component drop me a message
- INImagePreview-Demo
iPhone Interview Questions
Interviewing people is always hard, since you have to assess the candidate in several ways. That includes the knowledge relevant to your industry, or if that person fits into your organization’s work style or habits, if the person can work under heavy workload – but interviewing candidates also means that you have to give a good impression about yourself and your company. The hard part is that you need to do this in a really short timeframe which complicates things a bit …
There are a couple of good books that focus this area, one of the books which i know and read is “96 Great Interview Questions to Ask before you hire” but there are a couple of good others as well.
Recently I was given the task of interviewing candidates for positions in iPhone development – and besides the fact that i wasn’t really sure how to approach and conduct an interview (that was the time when i bought the book i linked above) – i needed a bit of help on the actual technical questions i could ask on iOS development, but at that time there were no good resources i could find on this topic.
So I decided to write up a list of iphone interview questions that could serve as a good starting point for Objective-C and Cocoa development topics. Also i intend to update this list later when i will have more information to add – hoping to build a comprehensive list of technical questions.
So here it is – a list of possible iphone interview questions:
—- Objective-C related —-
- identify basic OO concepts and the keywords Objective-C uses (interface, implementation, property, protocol, etc)
- what is a designated initializer, what is the pattern for the initializers and why ( if (self = [super ...] ) )
- basic memory management topics, like ownership retain/release/autorelease
- what happens if you add your just created object to a mutable array, and you release your object
- what happens if the array is released
- what happens if you remove the object from the array, and you try to use it
- trick: garbage collection on iPhone
- autorelease pool usage
- property declarations ( assign, nonatomic, readonly, retain, copy )
- trick: ask about the nonexistent atomic keyword, what does atomic mean
- ask on how to correctly implement a retaining setter property
- ask about the circular reference problem and delegates being usually saved with assign rather then retain
- what is the difference between the dot notation and using the square brackets
- what happens when we invoke a method on a nil pointer
- difference between nil and Nil
- what is KVO and related theory + methods to use when observing
- does KVO work with ivars too?
- protocols – maybe: main difference between c#/java interface and protocols
- what to do in a situation when a class doesn’t implement a method from a protocol
- what about multiple class inheritance
- what is fast enumeration
- class methods vs instance methods
- visibility of methods
- what is an actual class in Objective-c (struct)
- ask about the isa member
- ask about isKindOfClass isMemberOfClass
- root classes: NSObject, NSProxy
- how does proxy-ing work
- how to fake multiple class inheritance
- id type
- what happens during compilation if we invoke a method on an variable with the type id
- what happens runtime if the method exists
- what happens if the methods doesn’t exist
- pro and cons of using the type id
- what happens here(compile + runtime): NSString *s = [NSNumber numberWithInt:3]; int i = [s intValue];
- what are class categories and the () category
- what is an informal protocol
- what is a delegate, how to create one, and use one
- what is a selector, how to do a perform selector
- how to delay executing a selector
- what to do when the selector has more paramters (NSInvocation>
- how to start a selector on a background thread
- how to start a thread
- what is the first thing to do on a thread (autorelease pool)
- what is a runloop, and one very common place where it is used (timers, nsurlconnection)
- how to download something from the internet
- what is the difference between a synchronous and an asynchronous request
- small task: explain how to download an image from the internet, and show this in an image view – all this after a button is tapped on the view
- what are notifications, how to use them
- what is a memory warning, how do we respond to it
—- A bit more advanced topics —-
- when to use retainCount (never, and why)
- why shouldn’t we invoke instance methods in an initializer and the dealloc
- NSCoding, archiving
- NSCopying, why can’t we simply use our own objects as key in a dictionary, what to do to solve the problem ( and the difference between a shallow and a deep copy)
—- UIKit related —-
- what is a view, and a window
- difference between a view’s bounds and frame
- what is the resolution of the current available devices, difference between points and pixels (starting with iOS4)
- what is the responder chain, becomeFirstResponder
- what do IBOutlet and IBAction mean, what are they preprocessed to
- how do tableviews function
- what about multithreading and UIKit
- what to do when the keyboard appears and hides some parts of the UI that are important
- why should we release the outlets in viewDidUnload
- what is awakeFromNib, what is the difference between a nib and a xib
—- CoreData —-
- what is a context
- what about multi threading and core data usage
- what is an NSManagedObjectId – can we save it for later if the application was stopped
- what types of stores does core data support
- what is lazy loading, how does this relate to core data, situations when this can be handy
- how to ready only a few attributes of an entity
- what is an fetch result controller
- how to synchronize contexts
- how could one simulate an NSManagedObject (i’m thinking of the fact that all the properties are dynamic and not synthesized)
Okay – this probably is not a very organized list nor it is complete, but as i said i will get back and complete this list.
Also i would be really glad if you would drop a comment if you find this list useful, or want to add / correct something.
Using properties in initializers and dealloc in Objective-C
I’ve been using the plain old style [iVar release]; iVar = nil; style construct to free my variables for quite a long time in my dealloc methods.
But from an OO perspective it’s not always a good practice to use instance variables instead of properties, and on top of that if you have complex properties that encapsulate some kind of logic to access the instance variables than it makes even less sense to use the instance variables directly.
So after a while I’ve started using self.myProperty = nil; to free my variables, however it turned out that this wasn’t quite right either.
Let me explain a few things on how inheritance works. Say we have “Base” with one method named test :
@interface Base : NSObject {
}
- (void) test;
@end
@implementation Base
- (void) test {
NSLog(@"Invoked Base test.");
}
- (id) init {
if ( ( self = [super init] ) != nil ) {
[self test];
}
}
@end.
Now let’s have a second class “Inherit” that inherits from Base, and overrides the method test :
@interface Inherit : Base {
BOOL isSetUp;
}
- (void) test;
@end
@implementation Inherit
- (id) init {
if ( ( self = [super init] ) != nil ) {
isSetUp = YES;
}
}
- (void) test {
if ( !isSetUp ) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:nil userInfo:nil];
}
NSLog(@"Invoked Inherit test.");
}
As simple as it is, the Inherit class’ test method checks if the class was correctly initialized, and if everything is okay, then logs a message. There is nothing unusual in this, everything should work as expected, and if we would inherit from NSObject instead of Base then everything would be sunny.
But our base class is not NSObject, so things get complicated a bit. What’s happening is that the Inherit’s class initializer is invoked after the Base’s initializer, but the Base invokes the overridden test method, which will be invoked at a point when the Inherit class is not fully constructed.
Clearly this is a problem that could have been avoided if Base had not invoked a method in its initializer. Consequently the same problem exists if you invoke a method – or property – from dealloc.
There is really just very small chance that a subclass will override one of our properties or public methods which we use in our initializer or dealloc, so using properties in dealloc probably would never lead us to error. However theoretically speaking this could lead to errors.
So how do we solve this problem ?
First – avoid using public methods, properties in the initializers and dealloc since these can be overridden by your subclasses. Just always remember that your initializer runs before your subclass’ initializer, and your dealloc runs after your subclass’ dealloc.
You can do a macro to release your ivar, something like this:
#define RELEASE( ivar ) [ivar release], ivar = nil;
and you can use it in your dealloc method:
- (void) dealloc {
RELEASE( myVariable );
RELEASE( mySecondVariable );
[super dealloc];
}
Just a last quick note on this. When you publish your application, you should make sure that your ivars are all cleared in your dealloc, this way if you have an error in your program logic which tries accessing one of your released ivars the application would not crash.
On the other hand a crash is really what we want to happen while we are creating the application, so you could consider removing with a conditional flag the iVar = nil part during the implementation phase. What you could also do is to have your own singleton class that you set your ivars to, which will make sure to log a message if your ivar is used after your class’ dealloc has been invoked.
Aspect Oriented Programming in Objective-C
Aspect Oriented Programming is nice. It allows you to add functionality to objects that are not related to the program’s main logic – for this reason there are also called secondary or supporting functionality. You can read various publications on this a good starting point being Wikipedia’s article on AOP: http://en.wikipedia.org/wiki/Aspect-oriented_programming .
Let’s consider the following scenario: we have an instance of NSMutableArray and we would like to be notified for the following events: whenever its addObject: method is invoked and whenever it finished executing. We easily might need this functionality for the reason that we would like to validate the parameter addObject: receives against our business rules, and after the method finished executing we would like to send an NSNotification to other parts of the system letting them know that our array has changed.
The solution in Objective-C comes from its dynamic behavior, and it’s very flexible message sending mechanism, than can be used to create dynamic proxies that act like the original object but also add functionality to them.
So let’s start by creating an AOPProxy class that inherits from NSProxy and makes sure it behaves exactly like the object it proxies.
@interface AOPProxy : NSProxy {
@protected
id parentObject;
}
The parentObject is a reference to the original object for which we are going to act like a proxy and we are going to set this in the AOPProxy initializer.
The implementation of this AOPProxy has to override the following methods: -isKindOfClass: , -conformsToProtocol: , -respondsToSelector: , -methodSignatureForSelector: to be able to provide meta information to callers about itself. I’m going to show the implementation only in case of -isKindOfClass: since the implementation of the rest of the methods would look generally the same:
- (BOOL)isKindOfClass:(Class)aClass;
{
return [parentObject isKindOfClass:aClass];
}
After we made sure that our proxy will respond to the above methods, we need to make sure that our proxy will forward the method invocations to the original instance, and this happens in the -forwardInvocation: method:
- (void)forwardInvocation:(NSInvocation *)anInvocation;
{
SEL aSelector = [anInvocation selector];
// check if the parent object responds to the selector ...
if ( [parentObject respondsToSelector:aSelector] ) {
[anInvocation setTarget:parentObject];
// this is the point where we can jump in and execute our code ...
[anInvocation invoke];
}
}
Finally, extending this idea we can come up with methods that add a target and selector to be invoked before and after the [anInvocation invoke]; happens – which will give exactly the desired functionality of our proxy class.
Using the AOPProxy class we can do something like this:
NSMutableArray* testArray = [[AOPProxy alloc] initWithNewInstanceOfClass:[NSMutableArray class]];
[(AOPProxy*)testArray interceptMethodStartForSelector:@selector(addObject:)
withInterceptorTarget:self
interceptorSelector:@selector(addInterceptor:)];
[(AOPProxy*)testArray interceptMethodEndForSelector:@selector(addObject:)
withInterceptorTarget:self
interceptorSelector:@selector(addObjectEndInterceptor:)];
[testArray addObject:[NSNumber numberWithInt:1]];
[testArray release];
If you would like to check the code out you can download it from:https://github.com/moszi/AOP-in-Objective-C .
