Threads in IOS Objective-C


I have some data calculation method (let it be "myMethod:"), and I want to move the call to another thread because I don't want to block my main UI functionality. So, started to do some research on how to call my method on another thread. As far as I see, currently, there are a lot of different ways for doing that. Here's a list:
a) using pure threads (available since iOS 2.0):
[NSThread detachNewThreadSelector:@selector(myMethod:) toTarget:self withObject:_myParamsArray];
b) using a simple shortcut (available since iOS 2.0). Available from inherited NSObject but the method belongs to NSThread class too:
[self performSelectorInBackground:@selector(myMethod:) withObject:_myParamsArray];
c) using a new approach of Grand Central Dispatch queues (available since iOS 4.0):
dispatch_async(dispatch_get_global_queue(0, 0),
  ^ {
      [self myMethod:_myParamsArray];
    });
d) somehow, using some classes such as NSOperation, NSBlockOperation or NSOperationQueue, though not sure how exactly to do it (some example would be appreciated)
Currently, I have used case "b" but curious about pros and cons and other related suggestions on that.
==========================
Answer:
Usually, you would prefer the GCD approach.
It's simpler when it comes to synchronization/locking than pure threads (NSThread - pthread), and it may be more accurate in a performance perspective.
When using pure threads, the problem is you may have performance issues, depending on the number of available cores/processors.
For instance, if you have only one core, creating many threads may slow down your application, because the CPU will spend most of its time switching from one thread to another, saving the stack, registers, etc.
On the other hand, if you have a lot of cores available, it may be nice to create a lot of different threads.
This is where GCD helps, as it manages this for you. It will create the appropriate number of threads, based on the available system resources, to guarantee an optimal utilization, and schedule your actions appropriately.
However, for that reason, tasks launched with GCD may not be real-time.
So if you REALLY needs that a detached task runs immediately, use an explicit threads. Otherwise, use GCD.
Hope this will help you : )
EDIT
A note about performSelectorInBackground: it simply creates a new thread. So there's basically no difference with the NSThread approach.
EDIT 2
NSOperation related stuff are a bit different. On Mac OS X, they are implemented using GCD since version 10.6. Previous versions uses threads.
On iOS, they are implemented using threads only.
Reference
All of this is very well explained in the Concurrency Programming Guide. It discusses the GCD and thread approaches, with a lot of details about the uses and implementations.
If you haven't read it already, you should take a look.

Original post: 

SupressWarnings

Definition

The @SuppressWarnings annotation is defined in the Java Language Specification section 9.6.1.5. This section states:
The annotation type SuppressWarnings supports programmer control over warnings otherwise issued by the Java compiler. It contains a single element that is an array of String. If a program declaration is annotated with the annotation @SuppressWarnings(value = {S1, ... , Sk}), then a Java compiler must not report any warning identified by one of S1, ... , Sk if that warning would have been generated as a result of the annotated declaration or any of its parts.
Unchecked warnings are identified by the string "unchecked".
The subsequent section on @Deprecation also mentions that these warnings can be suppressed with@SuppressWarnings("deprecation").


Valid Warning Types

The only two warning strings that are mentioned in the specification itself are "unchecked" and "deprecation". However, the Sun JDK uses a larger set of strings in the compiler. You can determine the current set by executing:
javac -X

which will show you (among other things) the valid settings for -Xlint.

For example, Sun JDK 1.5 shows:
  • all - suppress all warnings from this code
  • deprecation - suppress warnings from using deprecated code
  • unchecked - suppress warnings from an unchecked call or an unchecked cast
  • fallthrough - suppress warnings if a switch falls through without finding a valid case (and no default)
  • path -
  • serial - suppress warnings if a Serializable class does not define a serialVersionUID
  • finally - suppress warnings from return within a finally (which will ignore return with the try)

And Sun JDK 1.6 adds:
  • cast
  • divzero - suppress warnings if integer divide by zero is detected
  • empty
  • overrides
  • none

IDEs and static analysis tools typically support a large number of other possible values for @SuppressWarnings. These values correspond to specific static analysis checks performed by the IDE.


Eclipse

The Eclipse warning values for Eclipse 3.3 are documented in the JDT docs.
  • all - suppress all warnings
  • boxing - suppress warnings relative to boxing/unboxing operations
  • cast - suppress warnings relative to cast operations
  • dep-ann - suppress warnings relative to deprecated annotation
  • deprecation - suppress warnings relative to deprecation
  • fallthrough - suppress warnings relative to missing breaks in switch statements
  • finally - suppress warnings relative to finally block that don't return
  • hiding - suppress warnings relative to locals that hide variable
  • incomplete-switch - suppress warnings relative to missing entries in a switch statement (enum case)
  • nls - suppress warnings relative to non-nls string literals
  • null - suppress warnings relative to null analysis
  • restriction - suppress warnings relative to usage of discouraged or forbidden references
  • serial - suppress warnings relative to missing serialVersionUID field for a serializable class
  • static-access - suppress warnings relative to incorrect static access
  • synthetic-access - suppress warnings relative to unoptimized access from inner classes
  • unchecked - suppress warnings relative to unchecked operations
  • unqualified-field-access - suppress warnings relative to field access unqualified
  • unused - suppress warnings relative to unused code


IntelliJ



NetBeans



Examples

An example of specifying a single warning:

@SuppressWarnings("unchecked")
public void methodWithScaryWarnings() {
List rawList = new ArrayList();
List stringList = (List)rawList;
}

An example of using two warnings:
@SuppressWarnings({"unchecked","deprecation"})
public void methodWithScaryWarnings() {
callDeprecatedMethod();
}

Creating a UITabBarController Programatically


I will show you how to create a UITabBarController application using only code. You’ll notice that this app doesn’t really “do” anything, it just switches between two table view controllers, but I think this will give you the framework to create a tab bar-based application and have the viewcontrollers do whatever you want in your own app. To the left you can see what the final app looks like (thank you to Apple Computer, Inc. for the tab button images which I took from the Elements model app).
Just some conditions on why I am doing this programmatically as an alternative of using Interface Builder (IB). The primary reason is that I don’t really like IB that much because it obfuscates a lot of what is going on and sometimes can make it hard to debug your applications. I’m not saying that I will never use IB, I’d just rather figure out how to do something first without using IB and then if I choose to use IB afterward I can, and I’ll know what’s going on under all of those covers that IB puts on top of your code.
Before we dive in, a quick note about UITabBarControllers. UITabBarControllers work by providing them an array of outlook controllers (table view controllers, navigation controllers, plain vanilla view controllers, etc.) and assigning that array to the viewControllers property of your UITabBarControllers object. That’s cute straightforward, except that there are some subtle details you need to get right or your program won’t work and most likely crash when you run it. One other important thing is that if you read Apple’s “View Controller Guide for iPhone OS” it will tell you that the correct way to create a UITabBarController object is with the subsequent code:
tabBarController = [[UITabBarController alloc] initWithNibName:nil bundle:nil];
This is WRONG. Instead, you just need to this:
tabBarController = [[UITabBarController alloc] init];
and that’s it. From searching various forums it seems like this is a common problem people have.
So let’s dive into this from scratch. I’m going to assume you have used XCode before and know at least some essential Objective-C and iPhone programming.
1. Open XCode and select File > New Project > Window-based Application (under iPhone OS Application). We’ll be doing all of this by hand so no need to have XCode stub out view controller classes for us or anything like that. Name the project whatever you want. I called mine “SimpleTabBar”.
2. Now we’ll create two table view controllers that will be shown when we click each tab in the tab bar. Right (Ctrl) click on the “Classes” folder and select Add > New File. Under iPhone OS > Cocoa Touch Classes select UITableViewController subclass and click next. Name your class something like “RootViewController.m” and don’t forget to create the .h file also. Do the same thing to generate your second view controller and call it something like “SecondViewController.m”.
3. You should now have three classes: SimpleTabBarAppDelegate, RootViewController, and SecondViewController. Within the border section of SimpleTabBarAppDelegate, add the following two instance variables (“window” will already be there for you). Declare them as properties also so that your code looks like this:
@interface SimpleTabBarAppDelegate : NSObject {
UIWindow *window;
UITabBarController *tabBarController;
}
@property (nonatomic, retain) UITabBarController *tabBarController;
@property (nonatomic, retain) UIWindow *window;
As you have probably guessed, tabBarController is the thing which will be used to create our tab bar controller. In my example, XCode also added an IBOutlet type in front of UIWindow in the property announcement for window, but you don’t need that so I impassive it.
4. Now go to the implementation section of SimpleTabBarAppDelegate and we’ll add some code to populate our tabBarController with an array of table view controllers (RootViewController and SecondViewController). I’ll break this down by sections. First, embrace the header files for the two view controller classes because we will be creatingview controller classes from within SimpleTabBarAppDelegate. Just under the line where it says #import “SimpleTabBarAppDelegate” insert the following two lines:
#import “RootViewController.h”
#import “SecondViewController.h”
Also add the following line:
@synthesize tabBarController;
just under @synthesize window;
5. Within the applicationDidFinishLaunching process, let’s instantiate a UINavigationController, within which each of our UITableViewControllers will live. This will make it nice for users to browse back and forth in your tables within your app.
// set up a local nav controller which we will reuse for each view controller
UINavigationController *localNavigationController;
6. Remember on top of I said that a UITabBarController class just holds an array of view controllers? So let’s get started doing that by creatingour tab bar controller item and an array that will hold all of those view controllers.
// create tab bar controller and array to hold the view controllers
tabBarController = [[UITabBarController alloc] init];
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:2];
Change “initWithCapacity” to however many tabs you will have, 2 in this case.
7. Now let’s get to work creating those view controllers and adding them to the array. First, let’s do the origin view controller. Note that I basically create the root view controller and then add it to the steering controller as its “root” view manager.
// setup the first view controller (Root view controller)
RootViewController *myViewController;
myViewController = [[RootViewController alloc] initWithTabBar];
// create the nav controller and add the root view controller as its first view
localNavigationController = [[UINavigationController alloc] initWithRootViewController:myViewController];
// add the new nav controller (with the root view controller inside it)
// to the array of controllers
[localControllersArray addObject:localNavigationController];
// release since we are done with this for now
[localNavigationController release];
[myViewController release];
For now don’t worry about the initWithTabBar method. It’s a custom init method that I’ll describe later.
8. Do the same thing for the second view controller (SecondViewController):
// setup the second view controller just like the firstSecondViewController *secondViewController;
secondViewController = [[SecondViewController alloc] initWithTabBar];
localNavigationController = [[UINavigationController alloc]
initWithRootViewController:secondViewController];
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[secondViewController release];
9. Now let’s load up our tab bar controller with the array of view controllers.
// load up our tab bar controller with the view controllers
tabBarController.viewControllers = localControllersArray;
// release the array because the tab bar controller now has it
[localControllersArray release];
// add the tabBarController as a subview in the window
[window addSubview:tabBarController.view];
// need this last line to display the window (and tab bar controller)
[window makeKeyAndVisible];
10. Practice good memory mgmt by releasing the window and tabBarController objects.
- (void)dealloc {
[tabBarController release];
[window release];
[super dealloc];
}
11. Ok – so that was the lions share of the work that is necessary. Now let’s go to each view manager and make some small changes to get this thing to compile and run! For each view controller, we are basically going to do the same thing but just change the titles so that it says “Tab1″ instead of “Tab2″ on the monitor. So I won’t show you the code from both view controllers, just make sure it is the same for each except for the text label changes. First, let’s declare our convention initialization method (“initWithTabBar”) in the interface section of RootViewController.h. As follows:
@interface RootViewController : UITableViewController {
}
-(id)initWithTabBar;
@end
12. Now let’s go to the realization section and put in the code for that custom init method. Note that there is more than one way to skin this cat, and you might want to just put this code into the “initWithStyle” method that is already there in case you want to specify a style for your table. But I did it this way just to show a custom initialization method in action.
-(id) initWithTabBar {
if ([self init]) {
//this is the label on the tab button itself
self.title = @”Tab1″;
//use whatever image you want and add it to your project
self.tabBarItem.image = [UIImage imageNamed:@"name_gray.png"];
// set the long name shown in the navigation bar at the top
self.navigationItem.title=@”Nav Title”;
}
return self;
}
I think the comments here are pretty self-explanatory, but let me know if you have any questions!
13. Go ahead and do the same thing in your SecondViewController class and change the titles to “Tab2″ etc.
14. Click the Compile and Go button and see the outcome of your work. Let me know if you have any questions!
Once you get this to work, you can add as many views and buttons as you want. Just create as many view controllers as you need and do again the steps in in your AppDelegate class for each view. Also don’t forget to alter the size of your array when you initialize it.
Source: http://www.iphonelife.co.uk/creating-a-uitabbarcontroller-programmatically/

Developing an Aumented Reality APP in 5 min

Deploy iPhone app to device to a jailbroken iPhone


A guide to deploy iPhone apps to your device with your jailbroken iPhone. Works on iOS 4.3.

Create Self-Signed Certificate

First you'll need to create a self signed certificate and patch your iPhone SDK to allow the use of this certificate:
  1. Launch Keychain Access.app. With no items selected, from the Keychain menu select Certificate Assistant, then Create a Certificate.
    • Name: iPhone Developer
    • Certificate Type: Code Signing
    • Let me override defaults: Yes
  2. Click Continue
    • Validity: 3650 days
  3. Click Continue
  4. Blank out the Email address field.
  5. Click Continue until complete.
    You should see "This root certificate is not trusted". This is expected.
  6. Set the iPhone SDK to allow the self-signed certificate to be used:
    sudo /usr/bin/sed -i .bak 's/XCiPhoneOSCodeSignContext/XCCodeSignContext/' /Developer/Platforms/iPhoneOS.platform/Info.plist
    If you have Xcode open, restart it for this change to take effect.

Enable Xcode's to Build on Jailbroken Device

  1. On your jailbroken iPhone, install the app AppSync.
  2. Remove SDK requirements for code sign and entitlements (I'm loving sed!):
    sudo /usr/bin/sed -i .bak '/_REQUIRED/N;s/YES/NO/' /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.2.sdk/SDKSettings.plist
  3. Conclude the requirement removal through patching Xcode. This means binary editing:
    cd /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Plug-ins/iPhoneOS\ Build\ System\ Support.xcplugin/Contents/MacOS/
    dd if=iPhoneOS\ Build\ System\ Support of=working bs=500 count=255
    printf "\xc3\x26\x00\x00" >> working/bin/mv -n iPhoneOS\ Build\ System\ Support iPhoneOS\ Build\ System\ Support.original/bin/mv working iPhoneOS\ Build\ System\ Support
    chmod a+x iPhoneOS\ Build\ System\ Support
    
    If you have Xcode open, restart it for this change (and last one) to take effect.
  4. Open "Project>Edit Project Settings" (from the menu). Click on the "Build" tab. Find "Code Signing Identity" and its child "Any iPhoneOS Device" in the list, and set both to the entry "Don't Code Sign":
    alt text
    After this feel free to undo step 3. At least in my case it went just fine.
  5. Setting Xcode to code sign with our custom made self-signed certificate (the first how-to). This step can probably be skipped if you don't want to be able to debug:
    mkdir /Developer/iphoneentitlements401
    cd /Developer/iphoneentitlements401
    curl -O http://www.alexwhittemore.com/iphone/gen_entitlements.txt
    mv gen_entitlements.txt gen_entitlements.py
    chmod 777 gen_entitlements.py
    Plug your iPhone in and open Xcode. Open Window>Organizer. Select the device from the list on the left hand side, and click "Use for development." You'll be prompted for a provisioning website login, click cancel. It's there to make legitimate provisioning easier, but doesn't make illegitimate not-provisioning more difficult.
    Now You have to do this last part for every new project you make. Go to the menu Project > New Build Phase > New Run Script Build Phase. In the window, copy/paste this:
    export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocateif [ "${PLATFORM_NAME}" == "iphoneos" ]; then
    /Developer/iphoneentitlements401/gen_entitlements.py "my.company.${PROJECT_NAME}" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent";
    codesign -f -s "iPhone Developer" --entitlements "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/"
    fi
    Source: http://stackoverflow.com/questions/246422/how-can-i-deploy-an-iphone-application-from-xcode-to-a-real-iphone-device