Τρίτη, 18 Δεκεμβρίου 2012

How to set up Doxygen for use in your Xcode Project



here is a great tutorial on the apple developer site with detail surrounding this process: 

http://developer.apple.com/tools/creatingdocsetswithdoxygen.html. However, I will try to add my own two cents to make the process go more smoothly and quicker for you!
Steps
1. Download the latest version of Doxygen here: http://www.stack.nl/~dimitri/doxygen/download.html#latestsrc
2. Drag and Drop Doxygen.app to your Applications folder to install Doxygen.
3. To create better looking documentation, download and install GraphViz here: http://www.ryandesign.com/graphviz/
  • The following bullets may not be needed (it wasn't for me), but just in case, here you are some settings you may need to adjust within Doxygen.
  • The installer will install dot in /usr/local/graphviz-x.y/bin/dot
  • To use dot from within doxygen, set HAVE_DOT to YES and DOT_PATH to /usr/local/graphviz-x.y/bin
    (where x.y is the version of graphviz you installed, e.g. 2.14).
4. Open and configure Doxygen.
  • There are essentially two views in Doxygen where you can edit your configuration files: Wizard and Expert. When you open Doxygen, it will open to the Wizard view. Some settings will need to be changed in the Expert view. If you open your Expert view window and there is nothing there, fear not...just look for the little grey dot on the right of the screen and pull it over to the left. This pesky problem took me quite some time to figure out. You can then click "next" to navigate through the expert view.
  • There are only a few changes you need to make to the configuration file.
    1. Set the working directory, project name, source code directory, etc... Basically, fill out the wizard project form.
    2. Go into the Expert view and scroll through until you see the HTML editing screen.
    • In this section, you will see GENERATE_DOCSET. Check the box.
    • Fill in a DOCSET_BUNDLE_ID (something like com.RonJeremy.MyProject). This will be used by Xcode to create a docset viewable inside Xcode.
  • Save your configuration file and run Doxygen to confirm that the documentation was created. You should be able to click "Show HTML Output" to confirm.
5. Follow the remaining instructions from the apple developer website: http://developer.apple.com/tools/creatingdocsetswithdoxygen.html. They are very straightforward, however, I ran into two issues:
  1. The only issue I ran into was when I first tried to view my docset. In Xcode, if you navigate to Help...Documentation, you should see a 'root' in the top left (see figure 1). If you don't, you must open the docset in your doxygen project root/html folder. This docset has the name you specified in your configuration (com.RonJeremy.MyProject).
  2. After running my Xcode build, I noticed the documentation was not being updated. To fix this, I had to go into my Xcode project folder and locate the file named: doxygen.config. In this file, I found that GENERATE_DOCSET was set to NO. Simply changing this to YES resulted in the correct behavior.
Once the above steps are complete, you should see some auto-generated documentation:



Generate documentation from source code


Generate documentation from source code

Doxygen is a documentation system for C++, C, Java, Objective-C, Python, IDL (Corba and Microsoft flavors), Fortran, VHDL, PHP, C#, and to some extent D.
It can help you in three ways:
  1. It can generate an on-line documentation browser (in HTML) and/or an off-line reference manual (in $\mbox{\LaTeX}$) from a set of documented source files. There is also support for generating output in RTF (MS-Word), PostScript, hyperlinked PDF, compressed HTML, and Unix man pages. The documentation is extracted directly from the sources, which makes it much easier to keep the documentation consistent with the source code.
  2. You can configure doxygen to extract the code structure from undocumented source files. This is very useful to quickly find your way in large source distributions. You can also visualize the relations between the various elements by means of include dependency graphs, inheritance diagrams, and collaboration diagrams, which are all generated automatically.
  3. You can also use doxygen for creating normal documentation (as I did for this manual).
Doxygen is developed under Linux and Mac OS X, but is set-up to be highly portable. As a result, it runs on most other Unix flavors as well. Furthermore, executables for Windows are available.

Τετάρτη, 7 Νοεμβρίου 2012

add 20 days (or month etc) on one NSDate


NSCalendar*       calendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents* components = [[NSDateComponents alloc] init];
components.day = 20;
NSDate* newDate = [calendar dateByAddingComponents: components toDate:STARTDATE options: 0];
    [exp setExpireDate:[newDate timeIntervalSinceReferenceDate]];

sort an array of objects with date property of them

finest solution i found was with block


sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
        NSDate *first = [(MYOBJECT *)a date] ;
        NSDate *second = [(MYOBJECT *)b date];
        return [first compare:second];
    }];

to reverse ascending to deciding just reverse the first and second

sortedArray = [originalArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
        NSDate *first = [(MYOBJECT *)a date] ;
        NSDate *second = [(MYOBJECT *)b date];
        return [second compare: first];
    }];

Delegate methode - Protocol and how to user a button inside on custom table view cell

Steps:

1. On .h of custom cell  create the protocol. In my protocol above i added also one more value the withExpense (yours could be something else)


@class PKAExpensesCell;
@class PKAExpenses;

@protocol ExpensesCellDelegate <NSObject>
- (void) expensesCell:(PKAExpensesCell *) cell payButtonPressed:(UIButton *) btn withExpense:(PKAExpenses *) expens;
@end

2. On .h of custom cell  create a delegate property and one for each other extra values you have added  on the above protocol
@property (nonatomic, assign) id<ExpensesCellDelegate> delegate;
@property (nonatomic, strong) PKAExpenses * expense;

3. Create an IBaction for the button you want to get the action (connect them properly)
- (IBAction)payButtonPressed:(id)sender;


4. Implement synthesize and the button action on .m of cell button file. 
@synthesize delegate,payButton,expense;

5.Implement the payButtonPressed methode at .m of cell 
- (IBAction)payButtonPressed:(id)sender {
    if (delegate && [delegate respondsToSelector:@selector(expensesCell: payButtonPressed: withExpense:)])
    {
        [delegate expensesCell:self payButtonPressed:payButton withExpense:expense];
    }
}

6. At viewController that has the tableview at .h file tell that viewController conforms the above protocole you have created. 
#import "PKAExpensesCell.h"

@interface PKAExpensesManagmentViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UITabBarDelegate, ExpensesCellDelegate>


7. At m. file of viewController at cell for row methode put the delegate
[cell setDelegate:self];
[cell setExpense:mylocalexpense];

8. Finally implement the required method from protocol at .m file of viewController and remember to reload data of mytableview if any data changed and need to be visible the effect. 
#pragma delegateProtocolForButtonsofCell
- (void) expensesCell:(PKAExpensesCell *) cell payButtonPressed:(UIButton *) btn withExpense:(PKAExpenses *)expens
{

    [expens setPaid:![expens paid]];
    [[self mytableview] reloadData];
    ........
}


In that way an user action on objects A view can create changes on object B view (etc).
The concept is
  • The B defines on A that is his delegate. 
  • The A when the action happened call one methode from his delegate. 
  • To ensure that B has that methode both of them follow the same protocol and more specific the A defines the protocol must be followed and the B conform it. 
I hope that will help someone :) 

best regards
Kostapappas

P.s. Most of the above solution is part of internet gathering solutions
PS2 The <NSOBJECT> at protocol is to ensure that compiler will understood the respondsToSelector method of delegate (because the delegate is <id>).









Παρασκευή, 31 Αυγούστου 2012

How to use the Scroll Down (interface) at IOS - from stackoverflow


Here's another way to do this that you might like better:
  1. Set the File's Owner placeholder's custom class to your view controller subclass.
  2. Create the UIScrollView as a top-level object in your nib. Set its size to the screen size (320x460) or just turn on a status bar under "Simulated Metrics".
  3. Connect the scroll view's delegate outlet to File's Owner.
  4. Set the File's Owner's view outlet to the scroll view.
  5. Create a UIView as another top-level object in your nib. This will be your content view.
  6. Set the content view's size to 320x700.
  7. Create a strong (or retain, if not using ARC) outlet named contentView in your view controller (File's Owner) and connect it to the content view.
  8. Put your buttons in the content view.
  9. In your view controller's viewDidLoad, do this:
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self.view addSubview:self.contentView];
        ((UIScrollView *)self.view).contentSize = self.contentView.frame.size;
    }
    
  10. In your view controller's viewDidUnload, do this:
    - (void)viewDidUnload {
        self.contentView = nil;
        [super viewDidUnload];
    }
    
share|edit|flag

Δευτέρα, 13 Αυγούστου 2012

Localizing Resources

copy paste from here


Don't localize numbers this way

Postby eaganj » Fri Jun 22, 2012 5:26 am
I just finished chapter 17 of the wonderful book, but this chapter feels weak, thin, and out of place. While the goal is certainly not to provide a complete overview of localization, it does provide one blaring example of what not to do when localizing numbers. In particular, the code that recommends showing the currency as :
CODE: SELECT ALL
NSString *currencySymbol = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol];
[[cell valueLabel] setText:[NSString stringWithFormat:@"%@%d", currencySymbol, [p valueInDollars]]];


will run and might appear correct, but is not. Not all regions display currencies in the same way. For example, while one might write $100 in the US, we write 100 (euro) in France. (Note: I had to write (euro) instead of the symbol in this message because of a text encoding bug.) Furthermore, some euro-zone regions write that as (euro) 100 (note the space). While completely understandable, writing (euro)100 just looks wrong. Fortunately, the NSNumberFormatter (which is just like the NSDateFormatter but for numbers) handles all these subtleties for us. So the above code should have been written as:
CODE: SELECT ALL
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[formatter setMaximumFractionDigits:0];
[[cell valueLabel] setText:[formatter stringFromNumber:[NSNumber numberWithInt:[p valueInDollars]]];



Παρασκευή, 20 Ιουλίου 2012

NSArray remove ObjectIdenticalTo VS removeObject:

copy (and not paste!) from book BigNerd Ranch iOS programming (2012) page 214


  • removeObject: goes to each object in the array and sends it the message isEqual:. A class can implement this method to return YES or NO based on its own determination
  • removeObjectIdenticalTo: removes an object if and only if it is exact same object as the one passed in this message. 

Κυριακή, 20 Μαΐου 2012

JSON format


Today i saw that twitter APIs sends data in JSON format :) 

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming LanguageStandard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.
JSON is built on two structures:
  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangeable with programming languages also be based on these structures.
In JSON, they take on these forms:
An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.

number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.

Whitespace can be inserted between any pair of tokens. Excepting a few encoding details, that completely describes the language.

Πέμπτη, 10 Μαΐου 2012

Name conventions - conventions


  • Ref, CGContextRef is a pointer to struct CGContext. The suffix Ref makes it easy to distinguish between pointers to C structures and pointers to Objective-C objects. 
  • At saved images you can use the @2x addition to annotate that this file is to be display if retina display exists. Example we save "apple.png" and "apple@2x.png". The first picture, it will be used on Non retina displays and the second will be used if retina display exists. The selection is automatic. example UIImage * i = [[UIImage imageNamed:@"apple.png"];
  • By convention, the reuse identifier  of every cell (from UITableViewCell) is simply the name of the cell class. If you have a table view that uses multiple styles of the same type of cell, you can suffix the reuse identifier with the name of that style, e.g. UITableViewCell-Default


  • NSCoder: Regardless of the type of the encoded value, there is always a key, which is a string that identifies which instance variable is being encoded. By convention, this key is the name of the instance variable being encoded. 
  • The key on NSUserDefaults (is a NSMutableDictionary) that holds the application preferences is the name of the application, the name of the preference, and the words PrefKey. This is the typical pattern for naming preference keys
  • Class meethods come first, followed by initializers, followed by any other methods. This is a convention that makes you header files easier to read. 

Τρίτη, 1 Μαΐου 2012

XCode 4.3.2 - Automatically set a breakpoint on any line that causes your application

Automatically set a breakpoint on any line that causes your application to crash or that causes an exception to be thrown.
To get the debugger to do this, we need to add a breakpoint for all exceptions.

  • Select the debug navigator. 
  • Then at the bottoms of the navigator area, click the + icon and select Add Exception Breakpoint. 
  • then click the Done button on the panel that pops up



#source: Big nerd ranch guide - iOS Programming - 3rd Edition

Παρασκευή, 20 Απριλίου 2012

Add "holes" to an array - NSNull

You cannot add nil to an array.
If you need to add "holes" to an array, you must use NSNull.

 NSNull is an object that represents nil and is used specifically for this task. The NSNull class defines a singleton object used to represent null values in collection objects (which don’t allow nil values).

[array addObject: [NSNull null]];

source:
iOS programming - the big nerd ranch guide (3rd edition)
documentation

Τετάρτη, 11 Απριλίου 2012

How to pass arguments in object C - xcode programes


in Xcode:
  • Choose Produce from menu
  • Choose Edit Scheme
  • Select Run ApplicationName on the left
  • Select Arguments tab
  • Add Arguments with + on Arguments Passed on Launch




Challenge page 252 - solution - The Big Nerd Ranch Guide Objective C

The Big Nerd Ranch Guide - Objective C-  page 252 challenge


int spaceCount(char * sentence)
{
    int numOfSpaces =0;
    int i=0;
    
    if (sentence){                          //protection for NULL sentence
        while (sentence[i] != '\0'){
            if (sentence[i++] == ' ')
                numOfSpaces++;
        }
    }
    return numOfSpaces;
}


chars - c strings and NSString

notes from Big Nerd Ranch Guide - Objective C


CHAR
char = a byte could be treated as a number or a character. (0-127)

  • 0-31 ASCII - are unprintable control codes
  • 32 is the space character
  • 127 is the delete
The non-printable characters can expressed using escape sequences that start with \.
  • \0 = null byte (0x00)
C string
A C string is a series of characters right next to each other in memory. the string ends when the character 0x00 is encountered
  • char * test = malloc(5)
  • test[4]='\0'

String literals
You can create a pointer to a string of characters (terminated with the zero character) by putting the string in quotes.
  • char *start = "love";
DANGER: literals strings are CONSTANT. Don't try to change them!

To enable the compiler to warn you about writing to constant parts of memory, you can use the 
  • const modifier
  • const char * text= "test"; !Read-only variable is not assignable

C string to NSString
char *cstring = "ohmy!";
NSString *y = [NSString stringWithCstring:cstring encoding: NSUTF8StringEncoding];

NSString to C string
NSString *mystring = @"noway!";
const char *cstring = NULL;
        if ([mystring canBeConvertedToEncoding:NSUTF8StringEncoding]) {
            cstring = [mystring cStringUsingEncoding:NSUTF8StringEncoding];
        }

Κυριακή, 8 Απριλίου 2012

Bitwise operator OR and AND - in objective C - Exclusive OR - Complements - Shifting and Enum


  • | is the bitwise-OR operator in C. 


You will see the bitwise-OR operator a lot in Cocoa and iOS programming.
You can use bitwise-OR together the constants that represent the particular aspects you want.


NSError *e;
NSDataDetector *d = [NSDataDetector dataDetectorWithTypes:
                                             NSTextCheckingTypePhoneNumber | NSTextCheckingTypeDate
                                             error:&e];


  • In objective-C we use bitwise-AND (&) to see if a certain bit, or flag is on

if ([currentDetector checkingTypes] & NSTextCheckingTypePhoneNumber){
    NSLog (@"This one is looking for phone numbers");
}



  • ^ exclusive OR (XOR) - two bytes together to create a third (beware is not exponentiation operator=pow())
  • complement is the byt that is the exact opposite of another (reverse all the 0 to 1 and all the 1 becomes 0).
  • A<<2. << Left-shift. Every time you left -shift a number one place, you double tis value.
  • A>>1. >>Right-shift. Every time you right-shift a number one place, you half its value (if it is odd round down).

An elegant way to declare the bit-masks with enum
enum {
 UIDataDetectorTypePhoneNumber = 1 << 0,
 UIDataDetectorTypeLink                = 1 << 1,
 UIDataDetectorTyprAddress           = 1 << 2,
 UIDataDetectorTypeNone               =0,
 UIDataDetectorTypeAll                   = NSUIntegerMax
};




examples from The big Nerd Ranch Guide - Objective C 

Challenge page 235 The Big Nerd Ranch Guide - Objective C

pass the block anonymously as an argument to enumerateOBjectsUsingblock: 


[oldStrings enumerateObjectsUsingBlock:^(id string, NSUInteger i, BOOL *stop) {
            NSRange yRange = [string rangeOfString:@"y"
                                           options:NSCaseInsensitiveSearch];
            //Did I find a y?
            if (yRange.location != NSNotFound) {
                *stop = YES;    //Prevent further iterations
                return;         //Stop this iteration
            }
            NSMutableString *newString = [NSMutableString stringWithString:string];
            //Iterate over the array of vowels, replacing occurrences of each
            //with an empty string
            for (NSString *s in vowels) {
                NSRange fullRange = NSMakeRange(0, [newString length]);
                [newString replaceOccurrencesOfString:s
                                           withString:@""
                                              options:NSCaseInsensitiveSearch
                                                range:fullRange];
            }
            [newStrings addObject:newString];
        }];


add a notification update with block 

[[NSNotificationCenter defaultCenter] addObserverForNameNSSystemTimeZoneDidChangeNotification 
                                                          object:nil 
                                                           queue:nil
                                                      usingBlock: ^(NSNotification *note){
                                                          NSLog (@"The system time zone has changed!");    
                                                      }];

Blocks

^(double div, double divisor) {
  double quotient = div / divisor;
  return quotient;
};

^: identifies a block

Block can take arguments

If you want to access a block by a name, we have to assign it to a block variable.

void (^devow) (id, NSUInteger, BOOL *)
Block variable declaration


notice that the block assignment ends with a semi-colon just like any variable assignment would.

You can use typedef to declare a block at the start of top of the file like
typedef void (^ArrayEnumerationBlock) (id, NSUInteger, BOOL *);

Rather to write: void (^devowelizer) (id, NSUINteger, BOOL *);
you can   write: ArrayEnumerationBlock devowelizer;

If a block returns a value you can call that block variable like a function

double (^divinationBlock) (double, double) = ^(double k, double j) {
            return k/j;
}

Blocks are created and stored on the stack and will be destroyed (with the stack) when the function or method that created the block returns. To copy a block from the stack to the heap, you send it the copy message:
ArrayEnumerationBlock iVarSomething = [something copy]; (now the new block variable is a pointer to the block). Methods that takes blocks as arguments, are expected to copy blocks passed to them.
A heap-based block behaving like an object comes with some memory management issues:

#Source: The Big Nerd Ranch Guide (Objective C) - kindle version


  • external variables are captured by the block when the copy is made.
  • to avoid retain cycles declare a __weak pointer outside the block
  • variables captured by a block are constant within the block and you cannot change their values (you can still send the object messages that can change its contents, you cannot modify the pointer itself).
  • if you want to change them you need to use __block otherwise you get compilation error.
__block int counter =0 ;
void (^counterBlock) () = ^ {counter++;};
...
counterBlock (); //Increments counter to 1
counterBlock ();//Increments counter to 2





Σάββατο, 7 Απριλίου 2012

Categories

An easy way to add methods to any existing class.

#import "ClassName.h"
@interface ClassName ( CategoryName )
// method declarations
@end

From Documentation:
How You Can Use Categories
There are several ways in which you can use categories:
  • To extend classes defined by other implementorsFor example, you can add methods to the classes defined in the Cocoa frameworks. The added methods are inherited by subclasses and are indistinguishable at runtime from the original methods of the class. 
  • As an alternative to a subclassRather than define a subclass to extend an existing class, through a category you can add methods to the class directly. For example, you could add categories to NSArray and other Cocoa classes. As in the case of a subclass, you don’t need source code for the class you’re extending.
  • To distribute the implementation of a new class into multiple source files For example, you could group the methods of a large class into several categories and put each category in its own file. When used like this, categories can benefit the development process in a number of ways—they:
    • Provide a simple way of grouping related methods. Similar methods defined in different classes can be kept together in the same source file.
    • Simplify the management of a large class when several developers contribute to the class definition.
    • Let you achieve some of the benefits of incremental compilation for a very large class.
    • Can help improve locality of reference for commonly used methods.
    • Enable you to configure a class differently for separate applications, without having to maintain different versions of the same source code.
  • To declare informal protocols See “Informal Protocols ,” as discussed under “Declaring Interfaces for Others to Implement.”
Although the Objective-C language currently allows you to use a category to override methods the class inherits, or even methods declared in the class interface, you are strongly discouraged from doing so. A category is not a substitute for a subclass. There are several significant shortcomings to using a category to override methods:
  • When a category overrides an inherited method, the method in the category can, as usual, invoke the inherited implementation via a message to super. However, if a category overrides a method that exists in the category's class, there is no way to invoke the original implementation.
  • A category cannot reliably override methods declared in another category of the same class.This issue is of particular significance because many of the Cocoa classes are implemented using categories. A framework-defined method you try to override may itself have been implemented in a category, and so which implementation takes precedence is not defined.
  • The very presence of some category methods may cause behavior changes across all frameworks. For example, if you override the windowWillClose: delegate method in a category on NSObject, all window delegates in your program then respond using the category method; the behavior of all your instances of NSWindow may change. Categories you add on a framework class may cause mysterious changes in behavior and lead to crashes.

Παρασκευή, 6 Απριλίου 2012

What Is Key-Value Coding?


What Is Key-Value Coding?

Key-value coding is a mechanism for accessing an object’s properties indirectly, using strings to identify properties, rather than through invocation of an accessor method or accessing them directly through instance variables. In essence, key-value coding defines the patterns and method signatures that your application’s accessor methods implement.
Accessor methods, as the name suggests, provide access to your application’s data model’s property values. There are two basic forms of accessor—get accessors and set accessors. Get accessors, also referred to as getters, return the values of a property. Set accessors, also referred to as setters, set the value of a property. There are getter and setter variants for dealing with both object attributes and to-many relationships.
Implementing key-value coding compliant accessors in your application is an important design principle. Accessors help to enforce proper data encapsulation, isolatememory management to centralized locations, and facilitate integration with other technologies such as key-value observing, Core Data, Cocoa bindings, and scriptability. Key-value coding methods can, in many cases, also be utilized to simplify your application’s code. See Model Object Implementation Guide for more guidance on why your application should implement key-value coding compliant accessors and make use of them.
The essential methods for key-value coding are declared in the NSKeyValueCoding Objective-C informal protocol and default implementations are provided by NSObject.
Key-value coding supports properties with object values, as well as the scalar types and structs. Non-object parameters and return types are detected and automatically wrapped, and unwrapped, as described in “Scalar and Structure Support.”

examples:
Object types:
[a setProductName:@"Washing Machine"]
[a setValue:@"Washing Machine" forKey:@"productName"];

[a valueForKey:@"productName"]

Non-object types
[a setVoltage:240];
[a setValue:[NSNumber numberWithInt:240] forKey:@"voltage"];

some notes from The Big Nerd Ranch Guide:
Note that even though you have no accessor methods for one object, the variable can still be set and read from others methods (via key-value coding). This is an obvious violation of the idea of object encapsulation - methods of an object are public, but the instance variables are delicate and should be kept private. If key-value coding weren't astonishingly useful, no one would tolerate it.

Charbonneau is correct. I get an XML feed in which corresponds to an object on the iPhone/Mac client. Typically it'll be something like <user><name>Bob</name><age>43</age></user> I had a method before that would key/value code NSDictionary instances. – Coocoo4Cocoa Dec 18 '08 at 20:53

Πέμπτη, 5 Απριλίου 2012

The Designated Initializer

From the Documentation:

The designated initializer is the method in each class that guarantees inherited instance variables are initialized (by sending a message to super to perform an inherited method). It’s also the method that does most of the work, and the one that other initialization methods in the same class invoke. It’s a Cocoa convention that the designated initializer is always the method that allows the most freedom to determine the character of a new instance (usually this is the one with the most parameters, but not always).

  • It’s important to know the designated initializer when defining a subclass
  • General principle: The designated initializer in a class must, through a message to super, invoke the designated initializer in a superclass.
From the Big Nerd Ranch Guide:
"A class has only one designated initializer method. If the class has other initializers, then the implementation of those initializers must call (directly or indirectly) the designated initializer. 
  • Thus, the designated initializer acts as a funnel-point.
  • When you create a class whose designated initializer has a different name than its superclass's designated initializer (as you did in Appliance and OwnedAppliance), you have a responsibility to document that in the header file. 
  • If a class has several initializers, only one should do the real work. That method is known as the designated initializer. All other initializers should call, either directly or indirectly, the designated initializer. 
  • The designated initializer will call the superclass's designated initializer before initializing its instance variables
  • If the designated initializer of your class has a different name than the designated initializer of its superclass, you must override the superclass's designated initializer so that it calls the new designated initializer.
  • if you have several initializers, clearly document which is the designated initializer in the header. 


Wy shouldn't I use accessor methodes in an init method?

First: Apples Documentation says so...

Don’t Use Accessor Methods in Initializer Methods and dealloc
The only places you shouldn’t use accessor methods to set an instance variable are in initializer methods and dealloc. To initialize a counter object with a number object representing zero, you might implement an init method as follows:
- init {

    self = [super init];

    if (self) {

        _count = [[NSNumber alloc] initWithInteger:0];

    }

    return self;

}

To allow a counter to be initialized with a count other than zero, you might implement an initWithCount: method as follows:
- initWithCount:(NSNumber *)startingCount {

    self = [super init];

    if (self) {

        _count = [startingCount copy];

    }

    return self;

}

Since the Counter class has an object instance variable, you must also implement a dealloc method. It should relinquish ownership of any instance variables by sending them a release message, and ultimately it should invoke super’s implementation:
- (void)dealloc {

    [_count release];

    [super dealloc];

}



What stackoverflow says? 

  • It's basically a guideline to minimize the potential for bugs.
  • It is all about using idiomatically consistent code. If you pattern all of your code appropriately there are sets of rules that guarantee that using an accessor in init/dealloc is safe.





What Big Nerd Ranch guide says?
"..In most cases, there is a little reason to do one over the other, but it makes for a great argument. The argument goes like this: The assign guy says, "You can't use an accessor method in an init method! The accessor asumes that the object is ready for work, and it isn't ready for work until after the init method is complete." Then the accessor method guy says, "Oh, come on. In the real world that is almost never an issue. My accessor method might be taking care of other stuff for me. I use my accessor anytime I set that variable." In reality, either approach will work in the cast majority of cases.