What are best practices that you use when writing Objective-C and Cocoa?

123,235

Solution 1

There are a few things I have started to do that I do not think are standard:

1) With the advent of properties, I no longer use "_" to prefix "private" class variables. After all, if a variable can be accessed by other classes shouldn't there be a property for it? I always disliked the "_" prefix for making code uglier, and now I can leave it out.

2) Speaking of private things, I prefer to place private method definitions within the .m file in a class extension like so:

#import "MyClass.h"

@interface MyClass ()
- (void) someMethod;
- (void) someOtherMethod;
@end

@implementation MyClass

Why clutter up the .h file with things outsiders should not care about? The empty () works for private categories in the .m file, and issues compile warnings if you do not implement the methods declared.

3) I have taken to putting dealloc at the top of the .m file, just below the @synthesize directives. Shouldn't what you dealloc be at the top of the list of things you want to think about in a class? That is especially true in an environment like the iPhone.

3.5) In table cells, make every element (including the cell itself) opaque for performance. That means setting the appropriate background color in everything.

3.6) When using an NSURLConnection, as a rule you may well want to implement the delegate method:

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
      return nil;
}

I find most web calls are very singular and it's more the exception than the rule you'll be wanting responses cached, especially for web service calls. Implementing the method as shown disables caching of responses.

Also of interest, are some good iPhone specific tips from Joseph Mattiello (received in an iPhone mailing list). There are more, but these were the most generally useful I thought (note that a few bits have now been slightly edited from the original to include details offered in responses):

4) Only use double precision if you have to, such as when working with CoreLocation. Make sure you end your constants in 'f' to make gcc store them as floats.

float val = someFloat * 2.2f;

This is mostly important when someFloat may actually be a double, you don't need the mixed-mode math, since you're losing precision in 'val' on storage. While floating-point numbers are supported in hardware on iPhones, it may still take more time to do double-precision arithmetic as opposed to single precision. References:

On the older phones supposedly calculations operate at the same speed but you can have more single precision components in registers than doubles, so for many calculations single precision will end up being faster.

5) Set your properties as nonatomic. They're atomic by default and upon synthesis, semaphore code will be created to prevent multi-threading problems. 99% of you probably don't need to worry about this and the code is much less bloated and more memory-efficient when set to nonatomic.

6) SQLite can be a very, very fast way to cache large data sets. A map application for instance can cache its tiles into SQLite files. The most expensive part is disk I/O. Avoid many small writes by sending BEGIN; and COMMIT; between large blocks. We use a 2 second timer for instance that resets on each new submit. When it expires, we send COMMIT; , which causes all your writes to go in one large chunk. SQLite stores transaction data to disk and doing this Begin/End wrapping avoids creation of many transaction files, grouping all of the transactions into one file.

Also, SQL will block your GUI if it's on your main thread. If you have a very long query, It's a good idea to store your queries as static objects, and run your SQL on a separate thread. Make sure to wrap anything that modifies the database for query strings in @synchronize() {} blocks. For short queries just leave things on the main thread for easier convenience.

More SQLite optimization tips are here, though the document appears out of date many of the points are probably still good;

http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html

Solution 2

Don't use unknown strings as format strings

When methods or functions take a format string argument, you should make sure that you have control over the content of the format string.

For example, when logging strings, it is tempting to pass the string variable as the sole argument to NSLog:

    NSString *aString = // get a string from somewhere;
    NSLog(aString);

The problem with this is that the string may contain characters that are interpreted as format strings. This can lead to erroneous output, crashes, and security problems. Instead, you should substitute the string variable into a format string:

    NSLog(@"%@", aString);

Solution 3

Use standard Cocoa naming and formatting conventions and terminology rather than whatever you're used to from another environment. There are lots of Cocoa developers out there, and when another one of them starts working with your code, it'll be much more approachable if it looks and feels similar to other Cocoa code.

Examples of what to do and what not to do:

  • Don't declare id m_something; in an object's interface and call it a member variable or field; use something or _something for its name and call it an instance variable.
  • Don't name a getter -getSomething; the proper Cocoa name is just -something.
  • Don't name a setter -something:; it should be -setSomething:
  • The method name is interspersed with the arguments and includes colons; it's -[NSObject performSelector:withObject:], not NSObject::performSelector.
  • Use inter-caps (CamelCase) in method names, parameters, variables, class names, etc. rather than underbars (underscores).
  • Class names start with an upper-case letter, variable and method names with lower-case.

Whatever else you do, don't use Win16/Win32-style Hungarian notation. Even Microsoft gave up on that with the move to the .NET platform.

Solution 4

IBOutlets

Historically, memory management of outlets has been poor. Current best practice is to declare outlets as properties:

@interface MyClass :NSObject {
    NSTextField *textField;
}
@property (nonatomic, retain) IBOutlet NSTextField *textField;
@end

Using properties makes the memory management semantics clear; it also provides a consistent pattern if you use instance variable synthesis.

Solution 5

Use the LLVM/Clang Static Analyzer

NOTE: Under Xcode 4 this is now built into the IDE.

You use the Clang Static Analyzer to -- unsurprisingly -- analyse your C and Objective-C code (no C++ yet) on Mac OS X 10.5. It's trivial to install and use:

  1. Download the latest version from this page.
  2. From the command-line, cd to your project directory.
  3. Execute scan-build -k -V xcodebuild.

(There are some additional constraints etc., in particular you should analyze a project in its "Debug" configuration -- see http://clang.llvm.org/StaticAnalysisUsage.html for details -- the but that's more-or-less what it boils down to.)

The analyser then produces a set of web pages for you that shows likely memory management and other basic problems that the compiler is unable to detect.

Share:
123,235
pixel
Author by

pixel

Husband, Dad, User Experience Psycho, Software Engineer.

Updated on July 08, 2022

Comments

  • pixel
    pixel almost 2 years

    I know about the HIG (which is quite handy!), but what programming practices do you use when writing Objective-C, and more specifically when using Cocoa (or CocoaTouch).

  • SinisterMJ
    SinisterMJ over 15 years
    You could do that but I like to label it explicitly as a "private" section (more documentation than functional) though of course that's already plenty obvious from it being located in the .m file...
  • schwa
    schwa over 15 years
    Except there is a difference between private categories and class extensions: "Class extensions allow you to declare additional required API for a class in locations other than within the primary class @interface block, as illustrated in the following example:" See link in edit.
  • SinisterMJ
    SinisterMJ over 15 years
    I agree there is a difference where the compiler will warn you when you have not implemented CE methods - but I do not find that aspect very important when all the methods are in the same file, and all private. I still prefer the maintainability aspect of marking the forward reference block private
  • SinisterMJ
    SinisterMJ over 15 years
    I can see arguing it's more maintainable to have the compiler keep the CE block in alignment with your code, but that seems to me to happen naturally through compiler warnings as methods change and method declarations do not. I can see others preferring CE, it's obviously meant for this use.
  • schwa
    schwa over 15 years
    I really don't see (Private) as any more maintainable than (). If you're that worried then a good dose of comments might help. But obviously live and let live. YMMV etc.
  • SinisterMJ
    SinisterMJ over 15 years
    I like your answer, my advice would by do not use a category to store utility code unless you are about to replicate some code in more than one place and the code clearly belongs with the class you are about to categorfy...
  • Michael Buckley
    Michael Buckley over 15 years
    I'd just like to pipe in and voice my support for namespacing category methods. It just seems like the right thing to do.
  • SinisterMJ
    SinisterMJ over 15 years
    I would argue, don't use setSomething:/something at all - instead use properties. At this point there are few people that really need to target Tiger (the only reason not to use properties)
  • Chris Hanson
    Chris Hanson over 15 years
    Properties still generate accessor methods for you, and the getter=/setter= attributes on the property let you specify the names of the methods. In addition, you can use [foo something] syntax instead of foo.something syntax with properties. So accessor naming is still relevant.
  • mmalc
    mmalc over 15 years
    In general you should not use accessor methods in dealloc (or init).
  • mmalc
    mmalc over 15 years
    When using garbage collection, you are strongly discouraged from implementing a finalize method -- you should find other opportunities to clean up resources.
  • mmalc
    mmalc over 15 years
    This is not true. Whether or not you are responsible for releasing top-level objects depends on what class you inherit from and what platform you are using. See developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgm‌​t/… amongst others.
  • Adam Ernst
    Adam Ernst over 15 years
    I've been bitten by this one before.
  • Adam Ernst
    Adam Ernst over 15 years
    Nice tip-off about the double arithmetic.
  • schwa
    schwa over 15 years
    Apart from performance reasons (accessors are slightly slower than direct access) why shouldn't I use accessors in dealloc or init?
  • mmalc
    mmalc over 15 years
    (a) Performance reasons are perfectly adequate a reason in themselves (especially if your accessors are atomic). (b) You should avoid any side-effects that accessors may have. The latter is particularly an issue if your class may be subclassed.
  • KeremV
    KeremV over 15 years
    I'll note that if you are running on the modern runtime with synthesized ivars you must use accessors in dealloc. A lot of modern runtime code is GC, but not all of it.
  • melfar
    melfar over 15 years
    What test frameworks do you recommend?
  • Chris Hanson
    Chris Hanson over 15 years
    Xcode includes OCUnit, an Objective-C unit testing framework, and support for running bundles of unit tests as part of your build process.
  • Jason Medeiros
    Jason Medeiros over 15 years
    I'd suggest that you should put private methods in a class continuation. (i.e. @interface MyClass () ... @end in your .m)
  • slothbear
    slothbear about 15 years
    Looks like the link for "Cocoa's naming convention" has moved. Try developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgm‌​t/…
  • bbrown
    bbrown almost 15 years
    I had some trouble getting this to work until I followed these instructions: oiledmachine.com/posts/2009/01/06/…
  • bbrown
    bbrown almost 15 years
    These autorelease bugs have bitten me many, many times in my short iPhone development career. Consciously avoiding the situations would have mitigated considerably.
  • Kornel
    Kornel almost 15 years
    wouldn't loading of nib retain it twice then? (once in nib, second by assignment to property). Am I supposed to release those in dealloc?
  • aleemb
    aleemb almost 15 years
    Instead of #PRAGMA you can use a comment // Mark: [Section] which is more portable and works identically.
  • Werner
    Werner almost 15 years
    Unless there's a special syntax I'm missing, // Mark: does not add a label in Xcode's functions drop down menu, which is really half the reason of using it.
  • Frank Szczerba
    Frank Szczerba almost 15 years
    You have to nil the outlets in viewDidUnload (iPhone OS 3.0+) or in a custom setView: method to avoid leaks. Obviously you should release in dealloc as well.
  • teabot
    teabot almost 15 years
    As a Java developer who has written an abstract factory in Objective-C I find this intriguing. Would you mind explaining a little more how this works - perhaps with an example?
  • johne
    johne almost 15 years
    There's nothing subtle about this, the documentation clearly says that you are required to do this. From Memory Management Programming Guide for Cocoa: Additional cases of weak references in Cocoa include, but are not restricted to, table data sources, outline view items, notification observers, and miscellaneous targets and delegates. In most cases, the weak-referenced object is aware of the other object’s weak reference to it, as is the case for circular references, and is responsible for notifying the other object when it deallocates.
  • Clinton Blackmore
    Clinton Blackmore almost 15 years
    This is a great reference for someone comming from C++, where I did most of the things you advise against.
  • Michael
    Michael over 14 years
    Keep in mind that not everyone agrees with this style: weblog.bignerdranch.com/?p=95
  • Claudio Pierard
    Claudio Pierard over 14 years
    This is the way Apple does things too. "Beginning iPhone 3 development" mentions this change from previous versions too.
  • oefe
    oefe over 14 years
    In XCode 3.2.1 on Snow Leopard, it is already built in. You can either run it manually, using Run -> Build and Analyze, or you can enable it for all builds via the "Run Static Analyzer" build setting. Note that this tool presently only supports C and Objective-C, but not C++ / Objective-C++.
  • Nico
    Nico over 14 years
    And, if you can, turn on “Treat Warnings as Errors”. Allow no warning to exist.
  • Rhult
    Rhult over 14 years
    You need to use uppercase, "// MARK: ...", to get it to show up in the drop down.
  • Johan Kool
    Johan Kool over 14 years
    A more extended view on wether or not to use accessor methods/properties in -init and -dealloc methods can be found here: mikeash.com/?page=pyblog/…
  • Johan Kool
    Johan Kool over 14 years
    A handy script to setup your project with recommended warnings is available here: rentzsch.tumblr.com/post/237349423/hoseyifyxcodewarnings-scp‌​t
  • Pascal
    Pascal over 14 years
    There is a rather important advantage to use () instead of (Private) (or some other category name): You can redeclare properties as readwrite while to the public they are only readonly. :)
  • John Smith
    John Smith over 14 years
    Sometimes it is not possible to use the standard setters/getters. I had a case where the setter had to also save something to file/database etc... So the advice still stands for handcrafted setters/getters.
  • Chris Hanson
    Chris Hanson over 14 years
    A setter should not be causing something to be saved to the database. There's a reason Core Data has a -save: method on NSManagedObjectContext, rather than have setters generate immediate updates.
  • John Smith
    John Smith over 14 years
    it was not an option in my case. The core data method could not possibly work. Sometimes textbook advice must be overridden.
  • Chris Hanson
    Chris Hanson over 14 years
    I doubt it wasn't an option, it may have required revisiting your app architecture however. (To be clear: I'm not saying "You should have used Core Data." I'm saying "Setters shouldn't save to database.") Having a context to manage an object graph, rather than saving individual objects in it, is virtually always both possible and a better solution.
  • Casebash
    Casebash over 14 years
    Class extensions are now the preferred way for private methods: developer.apple.com/Mac/library/documentation/Cocoa/Conceptu‌​al/…
  • Casebash
    Casebash over 14 years
    Your advice about doubles on the iPhone is out of date stackoverflow.com/questions/1622729/…
  • Tejaswi Yerukalapudi
    Tejaswi Yerukalapudi about 14 years
    Wow, I'm just getting started on iPhone dev and this is incredible!
  • SinisterMJ
    SinisterMJ about 14 years
    Casebash - thanks for the link, although the info was out of date with the 3Gs it appears you have even more reason to use single precision FP than ever before! I updated that section of the answer.
  • Brian Postow
    Brian Postow about 14 years
    +1 if only for the roman numerals. I'd totally do that!
  • cduhn
    cduhn about 14 years
    Counter-point: For the past year and a half I've followed the exact opposite policy: "If it can be implemented in a category, do so." As a result my code is much more concise, more expressive, and easier to read than the verbose sample code that Apple provides. I've lost a total of about 10 minutes to one namespace conflict, and I've probably gained man-months from the efficiencies I've created for myself. To each their own, but I adopted this policy knowing the risks, and I'm extremely glad that I did.
  • NSResponder
    NSResponder about 14 years
    I'll just chime in here and mention that anything Chris says about Core Data should be taken as authoritative. He was one of the engineers who wrote it.
  • jkp
    jkp almost 14 years
    Have you ever heard anyone tell you that the singleton is an anti-pattern? There is a reason for this....I'm disappointed that singletons are still viewed as the answer to all ills by cocoa programmers.
  • adib
    adib almost 14 years
    I find the benefits of not using autorelease outweighs its costs (i.e. more memory leak bugs). Code on the main thread should be fairly short-running anyway (or otherwise you'll freeze up the UI) and for longer-running, memory-intensive background code, you can always wrap the memory-intensive portions in local autorelease pools.
  • Dave
    Dave almost 14 years
  • iwasrobbed
    iwasrobbed almost 14 years
    In regards to Finish what you start you can also use // TODO: to mark code for completion which will show up in the drop down.
  • Plumenator
    Plumenator almost 14 years
    You can even set Tab to indent and then do Cmd-A and Tab.
  • kirk.burleson
    kirk.burleson almost 14 years
    Do you still believe we don't need abstract factory classes after all the time that's past since you posted this answer?
  • Stephan Eggermont
    Stephan Eggermont over 13 years
    Hmm, the first example is already full of bullshit. Never document language idioms. If I'd find those kinds of comments in a header file, I wouldn't bother reading on.
  • Brock Woolf
    Brock Woolf over 13 years
    it's an easy one to forget. Important nonetheless
  • Joe D'Andrea
    Joe D'Andrea over 13 years
    Once ivars are dynamically synthesized down the road (for iOS apps), you'll be glad you put IBOutlets in properties!
  • Joe D'Andrea
    Joe D'Andrea over 13 years
    I mentioned this in another comment, but should have placed it here: Once dynamic ivar synthesis starts happening for iOS apps (if/when?), you'll be glad you put IBOutlet on the property vs. the ivar!
  • Nikolai Ruhe
    Nikolai Ruhe over 13 years
    This is only a concern when refraining from static typing. If the compiler knows the type, argument and return types can differ without problems. Personnaly, I find this not often to be a problem. Apple also has a lot of methods that have the same name but differ in return types. Finally, there's a compiler flag to warn you in ambiguous cases.
  • Sven
    Sven over 13 years
    I disagree. You should use autoreleased objects whenever possible. If they increase the memory footprint by too much you should use another NSAutoreleasePool. But only after you confirmed that this really is an issue. Premature optimization and all that...
  • Sven
    Sven over 13 years
    Also if you copy, mutableCopy, new or retain.
  • tc.
    tc. over 13 years
    Not out of date; entirely wrong: the original iPhone supported floats and doubles in hardware at approximately the same speed. SQLite also doesn't keep transactions in memory; they're journaled on disk. Only long queries block your UI; it's less messy to run everything in the main thread and use faster queries.
  • tc.
    tc. over 13 years
    -1. The singleton is definitely an anti-pattern when you decide that your app needs more than one database (sync, multiple users, ...).
  • SinisterMJ
    SinisterMJ over 13 years
    @tc: I corrected the SQL item about transactions, note that I myself did not write those last four or so items. I also clarified the part about moving queries to the background was for very long queries only (sometimes you just can't get them shorter). But to call the whole thing "wrong" because of a few points is I feel rather extreme. Also, the answer above already stated: "On the older phones supposedly calculations operate at the same speed" but note the part about the greater number of single precision registers making them still preferable.
  • JeremyP
    JeremyP over 13 years
    The bit about nonatomic properties is premature optimisation. It's better to leave them as default and change them to nonatomic if profiling demonstrates a significant performance improvement can be obtained.
  • SinisterMJ
    SinisterMJ over 13 years
    That optimization is not premature at all. There is no benefit to leaving them atomic and in fact presents a potential danger with deadlock if you don't know what you are doing and actually use them multi-threaded. It's a common technique recommended by many experienced ObjC developers and the default on applications like Accessorizer that generate property settings.
  • mxcl
    mxcl over 13 years
    I don't agree. If it's going to be a function and it applies to a Foundation object, and you can think of a good name, stick it in a category. Your code will be more readable. I think that really the salient point here is: do everything in moderation.
  • RickiG
    RickiG over 13 years
    I spend less than 40 sec. a day typing [someObject release] and reading the "extra line" when instantiating a new object, but I once burned through 17 hours to find an autorelease bug that would only show up in special cases and gave no coherent error in the console. So I agree with adib when he puts it like "I find the benefits of not using autorelease outweighs its costs".
  • Özgür
    Özgür over 13 years
    There is nothing wrong with using AutoreleasePool as long as you get the ownership of the object; in your example I would use properties: self.aVariable=[AClass convenienceMethod]; in fact, Autoreleased objects are the very reason to use while returning from the methods; that is the advice given by Apple and Stanford iPhone course.
  • Marcel Falliere
    Marcel Falliere over 13 years
    @mmalc : do you have some kind of proof for that ? the votes seems to believe you, but I'm skeptic.
  • Mike Weller
    Mike Weller over 13 years
    I agree with Sven. The primary goal should be code clarity and reducing coding errors, with memory optimization only where it is needed. Typing out a [[[Foo alloc] init] autorelease] is quick and you immediately deal with the issue of releasing this new object. When reading the code you don't have to hunt around for the corresponding release to make sure it isn't being leaked.
  • justin
    justin over 13 years
    +1 for point #5. i wish nonatomic were the default. atomic is pretty useless (imo) - the dev (or client) should know when multithreading is an issue or not, and they should address those issues appropriately. 'it usually works, although it's very time consuming' is not a 'feature'.
  • Andrew Ebling
    Andrew Ebling about 13 years
    Otherwise known as "Composition over inheritance".
  • Brandon DuRette
    Brandon DuRette about 13 years
    Admittedly, I'm new to iOS, but there are places in Apple's documentation where they seem to use "member variable" and "instance variable" interchangeably (for example bit.ly/hR8RGI), so I don't see that as a hard and fast rule.
  • TOMKA
    TOMKA about 13 years
    Also, if you want to target older Mac OS X systems (pre 10.5) you have no option but to use accessor methods.
  • eonil
    eonil about 13 years
    Lifecycle of autoreleased objects are well defined and determinable at enough level.
  • eonil
    eonil about 13 years
    If we follow Apple's naming convention guideline, this situation won't be happen :)
  • eonil
    eonil about 13 years
    Oh my eyes!!!!! I can't believe what I saw.
  • mmalc
    mmalc about 13 years
    The lifecycle is typically one cycle of the event loop. That means that temporary objects can accumulate over the course of handling a tap, a swipe, or whatever. Per the original reply, allowing this to happen is not best practice, particularly when you can exercise more direct control.
  • Eiko
    Eiko almost 13 years
    As to 3) I'll propose the opposite approach: Use manual retain/release wherever possible! Who knows how this code will be used - and if it will be used in a tight loop it can blow up your memory usage unnecessarily.
  • eonil
    eonil almost 13 years
    @Eiko That's just a Premature Optimization, can't be general guidance.
  • Eiko
    Eiko almost 13 years
    I think it's more a design thing, especially when working on model classes. I consider growing memory as a side effect, and that's not what I want to appear often. Worse, another developer who uses my code has no chance but to wrap expensive calls into autorelease pools (if possible at all - my objects might be sent to some other library code). And those problems are hard to diagnose later, but cheap to avoid in the first place. If you copy/autorelease objects that got passed in, you might be lost if they are much bigger than you expected. I am more relaxed with GUI code, though.
  • eonil
    eonil almost 13 years
    @Eiko I agree autorelease will hold memory longer generally, and manual retain/release can reduce memory consumption in the case. However it should be guidance for special case optimization (even you're feeling always!), can't be the reason to generalize premature optimization as practice. And in fact, your suggestion is not opposite from me. I mentioned it as case of really need :)
  • Tom Fobear
    Tom Fobear almost 13 years
    This is good advice for any programming language
  • Zaky German
    Zaky German almost 13 years
    The syntax of autoreleased provides much better code readability than the extra function calls of alloc init and the extra line for releasing. If your object doesn't get deallocated after a run loop cycle it means the object is retained by something else and wouldn't be dealloated even if you were releasing it "manually", the problem would not be "some autoreleasing bug"...
  • tc.
    tc. almost 13 years
    @Michael: The post you linked to disagrees with making IBOutlets retain, not with sticking IBOutlet on the property instead of the ivar.
  • brian
    brian almost 13 years
    @mmalc in the case where you are dealing with a lot of allocations within a single iteration of the runloop you can create a nested autorelease pool and drain that immediately. There is no need to be releasing objects manually.
  • Jeethu
    Jeethu over 12 years
    There's now an iOS specific version of the Debugging Magic page.
  • Naveen Shan
    Naveen Shan over 12 years
    Its better to use nil instead of NULL, because the NULL will not free up the memory.
  • Admin
    Admin over 12 years
    @NaveenShan nil == NULL. They are exactly the same except that nil is an id and NULL is a void *. Your statement isn't true.
  • Admin
    Admin over 12 years
    @iWasRobbed or a #warning which will show up in the compiler's output.
  • Admin
    Admin over 12 years
    I have this: #define SXRelease(o); o = nil and the same for CFRelease and free. This simplifies everything.
  • Ahti
    Ahti over 12 years
    @WTP yep, nil == NULL, but using nil is clearly the preferred way, if you look through apples example code fragments, theyre using nil everywhere, and as you said, nil is an id, which makes it preferrable over the void*, in cases where you send ids, that is.
  • Admin
    Admin over 12 years
    @Ahti exactly, and Nil (uppercase) is of type Class*. Even though they are all equal, using the wrong one can introduce nasty little bugs, especially in Objective-C++.
  • Sulthan
    Sulthan over 12 years
    Note there is a great controversy about this. Using setter in dealloc can produce a bug if you are not releasing properties in the correct order. However the same is valid when using release directly - another bugs can appear. Apple recommends using release in dealloc but they use setter in their implementation (e.g. releasing delegate in [UITableView dealloc])
  • Mrunal
    Mrunal over 12 years
    Regarding second point .... Private method declaration:: There is no need to write any category. I can still write methods without declaration and without any warning. Here is the way: - (void) myPrivateMethod {} - (void)myClassMethod { [self myPrivateMethod]; } Check this out...
  • Walt Sellers
    Walt Sellers over 12 years
    If you are in your object's main .m file, then using () allows you to place method definitions anywhere in the interface myObject section. If you declare as (Private), you get a warning if you don't put the definition in interface myObject (Private).
  • Tim
    Tim over 12 years
    The information about doubles here is flat out wrong I'm afraid. Even the linked question referenced as a source for (4) contradicts the statement completely. Once more: iDevices of all flavours support double precision math in hardware.
  • SinisterMJ
    SinisterMJ over 12 years
    @Tim Just because double precision math is supported in hardware does not make it faster than single precision math. Can you provide a link or example to show there is truly no difference or that it would be faster? Note my text in fact explicitly states double precision math is supported in hardware... and the links provided do not contradict, they show how single precision can be faster.
  • SinisterMJ
    SinisterMJ over 12 years
    @mrunal - that technique works only when your method is being called by methods that follow it. Often times for organizational reasons you may want to put a helper method after some other methods that call it - that's when the private category comes in. I don't always put method definitions in a private category myself, but it's important to know it's an option rather than structuring your methods unnaturally.
  • Tim
    Tim over 12 years
    @KendallHelmstetterGelner your edit addresses my objection perfectly; thanks. My issue wasn't with whether double or single precision was faster, it was with your claim that double precision math was emulated in software and not supported in the hardware. I should have been clearer.
  • SinisterMJ
    SinisterMJ over 12 years
    I see, thanks for clarifying. I was confused.
  • Mrunal
    Mrunal over 12 years
    @KendallHelmstetterGelner - May i know which kind of organizational reasons?
  • SinisterMJ
    SinisterMJ over 12 years
    Grouping all view controller methods together is one example, with helper methods located after at the end of a file so as to make them easier to find.
  • occulus
    occulus about 12 years
    Avoiding autorelease as a matter of principle is a great way to make your code less maintainable, more error prone and harder to understand for no good reason (most of the time).
  • Jonathan.
    Jonathan. about 12 years
    If you really want to write Private, then you can do (/*Private*/) and as it's a comment it's actually () and you can still declare properties
  • Danyal Aytekin
    Danyal Aytekin about 12 years
    Shouldn't it be nil rather than NULL?
  • Nikolai Ruhe
    Nikolai Ruhe about 12 years
    @KendallHelmstetterGelner Current versions of clang do not depend on method declarations for the current compilation unit any more. So they can now be left out from the class extension without harm.