UNOFFICIAL Cocoa-dev Frequently Asked Questions (for contact details, see below) Last Update 26 October 2004 ------------------------------ Subject: 0. Introduction This article is Copyright (c) 2003,2004 by Alastair Houghton. It is provided as a service to the Cocoa developer community, and may be freely distributed and reproduced as long as this copyright notice is left intact. Certain topics come up again and again on this list. Whilst they are good questions, a lot of time is wasted on repetitive responses, even more when controversial topics rear their ugly heads. To contact the maintainer of this FAQ, please post a message to the Cocoa-dev list (cocoa-dev@lists.apple.com), prefixing in the subject with FAQ:. That way, there won't be a problem if ownership of this document is handed-over at some point. Note that you need to be subscribed to the list in order to post to it. If you have a question that you think should be part of this FAQ, please send the question _and your answer_ to the FAQ maintainer. The maintainer reserves the right to amend, include or reject your submission as appropriate, although you will usually receive an explanation as to why your question was or was not accepted. If you have a service or product that you believe will be useful to the Cocoa community at large, the maintainer will consider mentioning it in the FAQ. There are no guarantees, and blatant plugs are certainly out... any decisions will be made on a case by case basis. Please note that it will help your case tremendously if you provide unbiased information about competing products and services (otherwise the maintainer will need to do the necessary research before adding any information, which could take some time). N.B. This document is UNOFFICIAL. It has no connection *whatsoever* with Apple... they did not write it and are not responsible for its accuracy or content. Any correspondence relating to the FAQ should be directed to the current FAQ maintainer. Some terms used this document are trademarks or registered trademarks of Apple, IBM, Motorola, Microsoft and others. All such uses are hereby acknowledged. ------------------------------ CONTENTS Subject: 1. Learning Cocoa ========================== 1.1 I'm new to programming and I'd like to learn Cocoa. What should I do? 1.2 I know C or C++ and I'd like to learn Cocoa. What should I do? 1.3 I know Java and I'd like to learn Cocoa. What should I do? 1.4 I know Perl/Python/AppleScript/ and I'd like to learn Cocoa. 1.5 I'm learning Cocoa... which book should I buy? 1.6 Where can I get Cocoa training? Subject: 2. Objective-C ======================= 2.1 Doesn't this section duplicate information from the comp.lang.objective-c FAQ? 2.2 Is Objective-C portable? Can I write cross-platform applications in it? 2.3 Is Objective-C++ portable? 2.4 What does #import do? 2.5 What are "id", "IMP", "SEL" and "nil"? 2.6 When should I use an IMP? 2.7 How fast are Objective-C messages? 2.8 When should I use a subclass? 2.9 I ignored the compiler warnings and my program doesn't work. 2.10 Why is Objective-C better/worse than ? 2.11 I prefer , because... Subject: 3. Cocoa ================== 3.1 Memory Allocation 3.1.1 Cocoa memory management is confusing. All those pointers and retain/releases make my head spin. 3.1.2 I created my object like this, but it crashes whenever I try to use it. 3.1.3 Can I declare an object on the stack? 3.1.4 I've been told I should always autorelease objects that I return from my class's methods. Surely that's inefficient? 3.1.5 Should I use -allocWithZone:[self zone] rather than just -alloc? 3.1.6 When I raise an exception, my application leaks objects. 3.1.7 My program leaks objects/memory. What can I do? 3.1.8 My program is crashing, and I think it might be because of a problem with autoreleased objects. What can I do? 3.2 Views & Drawing 3.2.1 My view is upside-down! 3.2.2 When I draw a line, it comes-out all thick and fuzzy. What's wrong? 3.2.3 Drawing is too slow. How can I speed it up? 3.2.4 I put one view on top of another in Interface Builder, and when I run my program they don't look right. 3.2.5 How do I draw ? 3.2.6 I looked at NSBezierPath, and I can't see how to draw an elliptic arc. 3.2.7 How do I draw a gradient fill? 3.2.8 I applied a transform to my view, but now my lines come-out all distorted. 3.2.9 My image is upside-down when I render it into my view. 3.2.10 I want my window to be completely transparent, outside of the area that I'm drawing, but when I set the window alpha, I still get Apple's pinstripes showing behind my view. What should I do? 3.2.11 I moved my view, but the changes aren't visible on the screen. 3.2.12 My drawing code runs, but I don't see the results immediately. 3.2.13 How can I draw into an NSImage? 3.2.14 How do I draw arrows on the ends of an NSBezierPath? 3.3 Distributed Objects 3.3.1 I wrote a server that uses Distributed Objects, but it doesn't seem to work if I run it as a Startup Item. What's going on? 3.4 Run-Loops & Event Handling 3.4.1 When a user clicks one part of my user-interface, my program may take several seconds to complete the required processing; this makes the beach-ball appear. What can I do to stop it? 3.4.2 Is there a way to make the run-loop generate events when the status of a file-descriptor changes, like select()? 3.5 Controls & Cells 3.5.1 I cannot find a standard Cocoa control that does what I want. Are there any third-party controls available? 3.5.2 How do I display text *and* an icon in an NSTableView, NSOutlineView or NSMatrix? 3.5.3 How do I constrain what people can type into my text fields? 3.5.4 How do I put an NSProgressIndicator (or some other NSView) into a table view? 3.6 Integrating with the System 3.6.1 How do I obtain the icon the Finder would use for a given type of file? 3.6.2 How do I launch the user's default ? 3.6.3 How do I perform a privileged operation? (e.g. as "root" or an administrator?) 3.6.4 How do I get that password box to appear? 3.7 Miscellaneous 3.7.1 What is NSNull and why am I getting one? 3.7.2 How do I do file operations? Should I use NSFileWrapper? 3.7.3 How do I do networking? Should I use NSSocketPort or NSPort? 3.7.4 I created an object in Interface Builder, and its outlets don't seem to be connected when my program is running. I've double-checked, and they're definitely connected in IB. What's going on? 3.7.5 How do I use a class that might not be available at run-time (for example because it is only available on newer releases of Mac OS X)? 3.8 Portability 3.8.1 Is code written with Cocoa portable? 3.8.2 Can I use Core Graphics or Core Foundation with GNUStep? 3.8.3 Can I use Carbon, Quicktime or other Apple APIs with GNUStep? 3.8.4 Can I use NIB files with GNUStep? 3.8.5 Can I read archived data saved by Cocoa using GNUStep? 3.8.6 Can I used Distributed Objects to communicate between Cocoa and GNUStep? 3.8.7 Where can I get GNUStep? Where can I find more information about GNUStep? 3.8.8 I wish Apple would bring-back YellowBox for Windows. Subject: 4. Miscellaneous ========================= 4.1.1 Should I use an installer? 4.1.2 My application used compile fine, but now I get syntax errors on lines where I've declared variables in the middle of a function/block. What's wrong? 4.1.3 The documentation is really hard to use. How can I search or browse it more easily? 4.1.4 Why does my program crash? 4.1.5 My method never gets called, but I'm sure I followed the documentation to the letter. 4.1.6 My program needs to look exactly like the Windows version to avoid confusing my users. How do I implement ? 4.1.7 Please could someone give me some programming-style pointers. 4.1.8 I'd like to use libXYZ in my program, but I can't get it to compile. 4.1.9 How do I use Altivec/Velocity Engine? 4.1.10 I think I found a spelling mistake in the FAQ. 4.1.11 Why is this FAQ plain text... wouldn't HTML look nicer? 4.1.12 How does Cocoa compare with ? 4.1.13 My program builds and runs fine, but when I try to run it from the Finder or give it to my friends/colleagues, it quits on launch. I'm using Xcode, and it used to work fine with Project Builder. 4.1.14 Is there a list of assigned Rendezvous service names? 4.1.15 Xcode says my build has failed but I don't see any error messages, or I see a message about undefined symbols but it doesn't say which. How do I get a better description of what is wrong? Subject: 5. Related documents ============================= 5.1 Apple 5.2 Cocoa-dev list archives 5.3 Omni Group's developer resources 5.4 Stepwise 5.5 comp.lang.objective-c FAQ 5.6 comp.lang.c FAQ 5.7 GNUStep 5.8 Usenet newsgroups 5.9 CocoaDev Wiki 5.10 MacOSX Guru 5.11 Cocoa Dev Central ------------------------------ Subject: 1. Learning Cocoa ========================== * 1.1 I'm new to programming and I'd like to learn Cocoa. What should I do? Start by learning C. Listed below are a number of books and other resources you can use to help you here. Please try to avoid asking questions about learning C on the Cocoa-dev list... the Usenet newsgroup comp.lang.c is a *much* better place to ask, not least because there are a larger number of expert C programmers reading that newsgroup than there are reading the Cocoa list. It is probably also worth mentioning that people will not take kindly to your posting questions not related to ANSI C (such as those about Mac programming) to comp.lang.c; for Macintosh related topics, consider using the Usenet newsgroup comp.sys.mac.programmer.help or one of Apple's mailing lists instead. Once you've learnt C, see 1.2. Books: The C Programming Language (2nd ed.) -- Brian W. Kernighan, Dennis M. Ritchie (Prentice Hall, April 1988). ISBN 0-13-110362-8 Programming in ANSI C (Revised edition: 1994) -- Kochan, Stephen (SAMS Publishing, April 1994). ISBN 0-672-30339-6 On the web: comp.lang.c FAQ http://www.eskimo.com/~scs/C-faq/faq.html Learn C/C++ Today http://www.cyberdiem.com/vin/learn.html Usenet: comp.lang.c comp.sys.mac.programmer.* * 1.2 I know C or C++ and I'd like to learn Cocoa. What should I do? First, make certain that your C is up to scratch. If it is, move on to Objective-C. Objective-C is the small superset of C that is typically used for Cocoa development. Questions about Objective-C may be directed to the list, or alternatively consider the Usenet group comp.lang.objective-c. A few resources useful for learning Objective-C are: Books: The Objective-C Programming Language *** ISBN & PUBLISHER FOR PRINTED VERSION? Programming in Objective-C -- Kochan, Stephen (SAMS Publishing, November 2003). ISBN 0-672-32586-1 (Not published yet, but the original C book was supposed to be good.) Objective-C: Object-Oriented Programming Techniques -- Pinson, Wiener. ISBN 0-201-50828-1 Additionally, most Cocoa books contain at least a chapter on learning Objective-C; see section 1.5 for a list of books specifically about Cocoa. On the web: comp.lang.objective-c FAQ http://www.faqs.org/faqs/computer-lang/Objective-C/faq/ The Objective-C Programming Language (HTML/PDF of the book above) http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/index.html Usenet: comp.lang.objective-c * 1.3 I know Java and I'd like to learn Cocoa. What should I do? You're in luck! You can already use Cocoa directly from Java. Having said that, if you are writing Mac OS X-native applications, you might be better off using Objective-C (in which case, see 1.2). By the way, please don't post Java questions to the mailing list unless they are related to Cocoa. There are other forums more appropriate for the discussion of general Java programming techniques, for example comp.lang.java, and its FAQ, which may be found at http://metalab.unc.edu/javafaq/javafaq.html * 1.4 I know Perl/Python/AppleScript/ and I'd like to learn Cocoa. Ideally, you need to start by learning C (see 1.1). It is possible to use Cocoa from some other languages (Python, Ruby and AppleScript all have bindings, for example), although it will help you to understand the documentation as well as allowing you to communicate better with other Cocoa-based developers if you know a little bit of Objective C. * 1.5 I'm learning Cocoa... which book should I buy? This is a very difficult question to answer, as people have widely differing opinions as to which book is best. If you're an experienced programmer, you'll probably like Cocoa Programming (Anguish, Buck and Yacktman). Otherwise, the following books are available: Cocoa Programming -- Anguish, Buck & Yacktman (SAMS Publishing, September 2002). ISBN 0-672-32230-7 Learning Cocoa with Objective-C (2nd ed.) -- Davidson, Apple Computer (O'Reilly & Associates, October 2002). ISBN 0-596-00301-3 Building Cocoa Applications: A Step by Step Guide -- Garfinkel & Mahoney (O'Reilly & Associates, May 2002). ISBN 0-596-00235-1 Cocoa Programming for Mac OS X -- Hillegass (Addison-Wesley, December 2001). ISBN 0-201-72683-1 Cocoa Recipes for Mac OS X -- Cheeseman (Peachpit Press, November 2002). ISBN 0-201-87801-1 Cocoa in a Nutshell: A Desktop Quick Reference -- Beam & Davidson (O'Reilly & Associates, May 2003). ISBN 0-596-00462-1 Cocoa Programming for Dummies -- Tejkowski (For Dummies, March 2003). ISBN 0-764-52613-8 Learning Cocoa -- Mott, Apple Computer (O'Reilly & Associates). ISBN 0-596-00160-6 Cocoa Design Patterns -- Buck (O'Reilly & Associates, September 2003). ISBN 0-596-00430-3 Instant Cocoa -- Feiler (Hungry Minds, Inc., April 2003). ISBN 0-764-53755-5 Mac OS X: Advanced Development Techniques -- Zobkiw (SAMS Publishing, April 2003). ISBN 0-672-32526-8 Recent threads on this precise topic can be found in the list archives at http://cocoa.mamasam.com A few specific threads to check-out: http://cocoa.mamasam.com/COCOADEV/2003/08/2/71524.php http://cocoa.mamasam.com/COCOADEV/2002/08/1/41960.php http://cocoa.mamasam.com/COCOADEV/2003/01/1/53787.php Additionally, Cocoadev has a useful list of books with reviews, here: http://www.cocoadev.com/index.pl?CocoaBooks * 1.6 Where can I get Cocoa training? There are two companies that offer instructor-led Cocoa programming courses: Apple and The Big Nerd Ranch. Both classes are 5 days long and cover the tools and techniques used by Cocoa programmers. The Big Nerd Ranch courses are taught by Aaron Hillegass, the author of "Cocoa Programming for Mac OS X". See http://www.bignerdranch.com or http://train.apple.com for more information. ------------------------------ Subject: 2. Objective-C ======================= * 2.1 Doesn't this section duplicate information from the comp.lang.objective-c FAQ? To some extent, yes. It isn't supposed to be a replacement for the comp.lang.objective-c FAQ, which you can find at http://www.faqs.org/faqs/computer-lang/Objective-C/faq/ but by its very nature it will cover some of the same topics. It is worth mentioning though that comp.lang.objective-c is about using Objective-C on *any* platform, whereas this FAQ is specifically targeting Cocoa (and, to a certain extent, GNUStep, but more of that later). * 2.2 Is Objective-C portable? Can I write cross-platform applications in it? Yes, it is, and yes, you can. However, there are a few obstacles if you want to write cross-platform Cocoa applications (see section 3). If you want to compile Objective-C on other platforms, you can either use the GNU Compiler or the Portable Object Compiler; see http://gcc.gnu.org http://users.pandora.be/stes/compiler.html * 2.3 Is Objective-C++ portable? No. Not yet, at any rate. Only the Apple version of GCC contains support for Objective-C++; apparently, Apple have contributed patches to support it to the FSF, so perhaps the "official" GCC will gain the ability to compile it in the future. For now, if you need to integrate C++ with Objective-C in a portable manner, you need to write a C API, either for your C++ objects or for your Objective-C objects. * 2.4 What does #import do? Experienced C programmers normally write #ifndef MYHEADER_H_ #define MYHEADER_H_ ... #endif /* MYHEADER_H_ */ around the contents of header files to prevent their contents from being included more than once in the same source file (these pre-processor statements are usually referred to as header guards). If you "#import" a file rather than "#include"ing it, the pre-processor guarantees that it won't even try to include its contents more than once, so you don't need the header guards. Some people strongly dislike #import, and will tell you that you should use #include instead. * 2.5 What are "id", "IMP", "SEL" and "nil"? "id", "IMP" and "SEL" are all types built-in to the Objective-C language. A variable of type id holds a pointer to an Objective-C object of any class. "nil" is a NULL pointer of type id. Messages sent to nil will have no effect, and, if they are declared as returning an object, will return nil. For portability reasons, you should not rely on the return value of messages sent to the nil object unless the message is declared as returning an object. A variable of type IMP holds a pointer to a method implementation, which can be used just like any other function pointer except that it requires two additional arguments; for example, given the class @interface CFAQDemoClass { } -(int)impMethodWithInt:(int)parameter; @end you could obtain an IMP using IMP myImp = [myDemoObject methodFor:@selector(impMethodWithInt:)]; and use it like this: int ret = ((int (*) (id, SEL, int)) myImp)(self, @selector(impMethodWithInt:), 103); There is normally no need to use an IMP in your programs (it is only present to permit certain specific optimisations). A variable of type SEL holds a selector value, which you can create using the @selector() built-in function. By the way, if you are asking a question this basic, you should probably read The Objective-C Programming Language at http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/index.html * 2.6 When should I use an IMP? You should only use an IMP if you need to optimise a particular section of your program. Before optimising, you should profile; otherwise you do not know what you need to optimise, or indeed whether there is any need to optimise at all. IMPs are good for the case where you are calling the same method over and over in a tight loop. However, they have disadvantages; for example, if you load a bundle into your application, you may find that your IMP is pointing at the wrong method! * 2.7 How fast are Objective-C messages? The name "message" might make you think that they are slow; however, they are actually quite fast. Here are some figures from a 1GHz PowerPC G4 (courtesy of Marcel Weiher): Operation | Time (ns) ------------------------------+------------ Increment (memory) variable | 2 Call through an IMP | 12 Local function call | 18 Cross-module function call | 37 Objective-C message | 54 atoi("1") | 182 Local function call refers to a call to a function in the same executable or dynamic object module. Cross-module function call is a call from one executable or dynamic object module into another. On current Apple versions of GCC, an Objective-C message results in a call to objc_msgSend(), which is itself a cross-module function call. That means that the actual method dispatch only takes 17ns (on average), which is pretty quick. * 2.8 When should I use a subclass? Subclassing is only appropriate in Objective-C when you are creating a new variant of a particular class. Before subclassing anything, answer the following questions: A. Is the class I'm creating a logically distinct sub-class of the class I'm subclassing? If not, then you are probably about to do something wrong. (For example, Boy and Girl would be appropriate sub-classes of Child; however, Adult should *not* be a subclass of Child, nor should Child be a subclass of Adult). B. Does the class I'm about to subclass provide delegate methods that would allow me to obtain the behaviour I'm looking for? If so, consider using delegation instead of inheritance. C. Am I subclassing just to add a few methods, leaving the rest of the class's behaviour intact? If so, consider using a category instead. The second and third questions are especially important if you have a background in C++ or Java; programmers that have used those languages are often over-enthusiastic about subclassing when they start using Objective-C. * 2.9 I ignored the compiler warnings and my program doesn't work. Read the compiler warnings. Ideally, you shouldn't be getting *any* compiler warnings when you build your program. * 2.10 Why is Objective C better/worse than ? Questions of this nature are hard to answer, and even harder to answer correctly because to do so requires someone with an expert knowledge of both the languages in question. It is also, to a certain extent, subjective, in that some people prefer certain styles of programming languages that are disliked by other people. Please try to avoid asking the list this question (in any variant); we have collectively answered it several times before, and the discussion tends to deviate quite quickly from the topic we are supposed to be discussing (Cocoa). It is generally the opinion of users of Objective C that they can achieve a greater amount in a shorter period than is possible other C-family OO languages, a fact that is in no small part attributed to the more dynamic nature of the type system; similar conclusions have generally been drawn by users of other languages with dynamic type systems (Forth, Lisp, Scheme and Smalltalk probably being the most popular). The two most commonly asked variants of this question relate to Java and C++; here is a quick table highlighting some of the differences between the languages. C ObjC Java C++ +--------------------------------- | Native OO? | - Y Y Y | Multiple Inheritance? | - - - Y | Abstract Classes? | - Y (1) Y Y | Access Control? | - Y (2) Y Y | Interfaces/Signatures/Protocols? | - Y Y - | Transparent Remoting? | - DO RMI - | (7) CORBA CORBA | Object Introspection? | - Y Y - | Categories? | - Y - - | Dynamic Typing? | - Y - - | Templates/Generics? | - - - Y | Exceptions? | - Y Y Y | Synchronized Blocks? | - Y (6) Y - | Can Use Existing C Libraries? | Y Y Y (4) Y (5) | Cross-platform Binaries? | - - Y - | Cross-platform Source Code? | Y Y Y Y | Built-in Security Model? | - - Y - | Fully Compiled? | Y Y - Y | Glueless OO Plugins? (3) | - Y Y - | Permits Run-time Alteration of | - Y -? - Classes? | | Language Complexity | Low Low Medium High | Supports Cocoa | - Y Y - | (1) Abstract classes are not a language feature in Objective C, however they do not need to be; they are simply classes that you do not instantiate. (2) Objective C only provides access control for member variables; it is not as widely used as the similar features in Java and C++, as ObjC programmers are generally more trusting of users of their classes. It is usual in Objective C to use naming conventions (specifically, a unique prefix) to label things as private, protected, etcetera. (3) Both ObjC and Java support introspection, hence it is possible to examine a class to determine whether it supports a specified interface. In C++, additional layers of software are necessary (e.g. COM). (4) Requires the use of JNI, and means that Java binary is no longer platform independent, as it requires a suitable compiled version of the C library code. This is relatively complicated. (5) Requires extern "C" { } wrappers. Some libraries may need extra work, for example because they use variable or function names that are C++ keywords; this can be complicated to fix. (6) This has just been added by Apple. (7) Transparent CORBA is by way of a third-party framework, ADORB, available at http://homepage.mac.com/v_ananiev/adorb/home.html Both Distributed Objects and ADORB are highly dynamic; they do not even require an IDL compiler! You can find many more language comparison charts on the Internet... for example, http://www.approximity.com/ruby/Comparison_rb_st_m_java.html or http://www.smallscript.com/Language%20Comparison%20Chart.asp * 2.11 I prefer , because... This list is about Cocoa, which is accessible from Objective C and Java. This is *not* a programming language advocacy list, so please do not treat it as one. ------------------------------ Subject: 3. Cocoa ================= 3.1 Memory Allocation --------------------- * 3.1.1 Cocoa memory management is confusing. All those pointers and retain/releases make my head spin. This appears to be a common problem. Fortunately it is easily resolved; follow the simple guidelines below and you will be fine: i) If you obtain an object by asking for a property of another object, you need to retain it if you expect to make use of it outside of the lifetime of that other object. For example, if my object has a colour property, and I wish to remember what colour it was after the object has been destroyed, I should retain it. ii) If you obtain an object from a container (like NSArray), you need to retain it if you expect to make use of it outside of the lifetime of the container. iii) If you obtain an object by any other means, you need to retain it if you wish to use it outside of the lifetime of the current autorelease pool. In practice, this could be as short as the function or method you are writing... for example, someone could write NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; myMethod(); [pool release]; around a call to your method. iv) If you explicitly create an object using any method with the words "copy", "alloc" or "new" in its name, you need to release it. v) If you explicitly retain an object, you need to release it. vi) The object ownership chain must not contain loops. If it does, then clumps of objects can leak; for example, consider the following: D ----> A ----> B ----> C ^ | | | \_______________/ where A, B and C are three objects and the arrows indicate a "retains" relationship (so D retained A, A retained B, B retained C, and C retained A). Notice that the reference count on A is 2, so when A is released (by whatever code owns D), A will not be de-allocated, and the reference counts on all objects in the loop remain at 1. There are also a number of very comprehensive articles available: Very simple rules for memory management in Cocoa - mmalcolm crawford http://www.stepwise.com/Articles/Technical/2001-03-11.01.html Hold Me, Use Me, Free Me - Don Yacktman http://www.stepwise.com/Articles/Technical/HoldMe.html Memory Management 101 - Erik Barzeski http://cocoadevcentral.com/articles/000055.php Memory Management in Objective-C - Michael Beam http://www.macdevcenter.com/pub/a/mac/2001/07/27/cocoa.html Introduction to Memory Management - Apple Computer http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html * 3.1.2 I created my object like this, but it crashes whenever I try to use it. You probably wrote MyClass *myObject; [myObject doSomething]; and expected it to work. You haven't actually created an object; instead, you've declared a pointer to one, and as you haven't initialised it, there is a very good chance that your program will crash. Allocate an object using [[MyClass alloc] init], and set the myObject pointer equal to the pointer it returns; for example MyClass *myObject = [[MyClass alloc] init]; [myObject doSomething]; [myObject release]; Notice that we've added a release... looking at the memory management rules in 3.1.1, you'll see that rule (iv) says that since we wrote "alloc" in our code, we need to release or autorelease the object in order to avoid a memory leak. * 3.1.3 Can I declare an object on the stack? No. Objective-C doesn't let you declare static object instances; you can only declare pointers to objects. * 3.1.4 I've been told I should always autorelease objects that I return from my class's methods. Surely that's inefficient? Yes. There are differing opinions within the developer community on this subject; some people feel that the advantages of always autoreleasing outweigh the disadvantages, and vice-versa. Apple currently say that you should, but as people have noticed, Apple's classes do not always follow that rule. It is best not to make assumptions about the lifetimes of objects returned by methods of other objects; that way, you cannot be caught-out. * 3.1.5 Should I use -allocWithZone:[self zone] rather than just -alloc? Probably not. Zones are an optimisation, and one that only works in certain cases; worse than that, when memory zone techniques do not work, they tend to make things worse rather than better. Unless you have a specific reason for using zones, avoid them. * 3.1.6 When I raise an exception, my application leaks objects. Quite probably. Objective-C doesn't (currently) have support for destruction of objects whose only references are pointers held in the local variables of functions whose stack frames are unwound by exception handling. Either don't use exceptions, or autorelease any object that might need to be destroyed if an exception occurs. (Apparently, NSAutoreleasePool objects *do* get destroyed during exception handling, so local declarations of those are fine.) * 3.1.7 My program leaks objects/memory. What can I do? First, remember that autoreleased objects are only released when their containing autorelease pool is released. Also remember that some objects are created once, but on-demand (i.e. *not* at start-up). Apple provide several tools to help you track down memory and object leaks, including: ObjectAlloc MallocDebug leaks heap malloc_history The first two are in /Developer/Applications, whilst the latter three are command line tools. In addition, you can set the environment variable MallocHelp to YES and run any program to see a list of other environment variables that you can set to enable debugging features in the Mac OS X implementation of malloc(). For example, under tcsh (the default shell), you might enter setenv MallocHelp=YES true while if you are using a Bourne shell (e.g. Bash), MallocHelp=YES /usr/bin/true will work. In addition to the Apple-supplied tools, Omni Group have a more sophisticated object tracking tool, OmniObjectMeter, that may be worth a look. * 3.1.8 My program is crashing, and I think it might be because of a problem with autoreleased objects. What can I do? There are a variety of variables you can use to control the behaviour of the autorelease mechanism; this will allow you to detect the code that is (for example) incorrectly releasing an autoreleased object. Take a look in /System/Library/Frameworks/Foundation.framework/Headers/NSDebug.h for more information. See also section 4.1.4, which deals with crashes. 3.2 Views & Drawing ------------------- * 3.2.1 My view is upside-down! Yes. Now that you're over the shock, let's discuss why. Either your view is returning YES from its -isFlipped method (in which case the positive Y axis runs downwards, the conventional direction for computer displays), or your view is returning NO, in which case the positive Y axis runs upwards. It is also possible that you have used NSAffineTransform to invert the axis, but given that you're surprised by the view not being the way up you thought it was, that probably isn't the problem. * 3.2.2 When I draw a line, it comes-out all thick and fuzzy. What's wrong? You're drawing at integer co-ordinate values. The default co-ordinate system used in Mac OS X has the integer values falling on the pixel *grid*, and not on the pixels themselves. That is, the bottom left hand pixel in a non-flipped view is a rectangle from (0.0, 0.0) to (1.0, 1.0), whose centre is at (0.5, 0.5). If you tell Mac OS X to draw a line from e.g. (5.0, 5.0) to (5.0, 105.0), it will do the best it can by putting half of the colour you wanted into each pixel either side of the line. To get a single-pixel line, offset your co-ordinates by 0.5 in each direction. For example, the diagram below shows what will happen if you draw three lines, all of the same colour, the first from (1.5, 1.5) to (12.5, 1.5), the second from (1.0, 3.5) to (12.0, 3.5) and the third from (1.0, 6.0) to (12.0, 6.0). 8.0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 7.0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | |::::|::::|::::|::::|::::|::::|::::|::::|::::|::::|::::| | | | |::::|::::|::::|::::|::::|::::|::::|::::|::::|::::|::::| | | 6.0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | |::::|::::|::::|::::|::::|::::|::::|::::|::::|::::|::::| | | | |::::|::::|::::|::::|::::|::::|::::|::::|::::|::::|::::| | | 5.0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 4.0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | |****|****|****|****|****|****|****|****|****|****|****| | | | |****|****|****|****|****|****|****|****|****|****|****| | | 3.0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 2.0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | |::::|****|****|****|****|****|****|****|****|****|****|::::| | | |::::|****|****|****|****|****|****|****|****|****|****|::::| | 1.0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 0.0 +----+----+----+----+----+----+----+----+----+----+----+----+----+----+ 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 Notice that the bottom line still has two light-coloured pixels, one at each end. This is because the default line end-cap style is NSButtLineCapStyle, which means that the ends of the line look like this: +------ ... ------+ | | X====== --- ======X | | +------ ... ------+ where the end-points of the line are marked by "X"s; so if you position the end-point of a horizontal or vertical line in the middle of a pixel, only half of that pixel will be set. * 3.2.3 Drawing is too slow. How can I speed it up? Either A. Optimise your drawing, by drawing only what you need and by minimising the complexity of any NSBezierPaths you are using (fewer lines make NSBezierPath render much faster, because it has to compute all of the self-intersections in order to get the antialiasing correct). B. Cache rendered data in an NSImage. This is probably worth doing for complex areas of a drawing that you don't expect to change very often. or C. Draw using OpenGL instead; this will take advantage of any hardware acceleration provided by your graphics card, but the result will not be of as high a quality. It may help (depending on your application) if you increase the flatness value, using Core Graphics' CGContextSetFlatness(), which will increase image quality at the expense of performance. Similarly, if you don't need antialiasing, you can turn it off with NSGraphicsContext's -setShouldAntialias:. Also, if you are using scaled images extensively, consider using NSGraphicsContext's -setImageInterpolation: method to reduce the interpolation quality. The reason that Quartz draws more slowly than other contemporary graphics systems is that it uses a more advanced imaging model and is capable of very high quality rendering. Quartz is a workstation-class graphics system, rather than an evolution of one of the consumer-oriented systems (QuickDraw, Windows GDI, GEM VDI et-cetera). There is an excellent section in Cocoa Programming that covers this topic (see Ch. 13 pp. 496 to 519). * 3.2.4 I put one view on top of another in Interface Builder, and when I run my program they don't look right. Cocoa doesn't support overlapping views. If a view belongs "on top of" another, then it should probably be a sub-view. This particular problem is likely to crop-up more often if you are coming from a Windows background, because dialog boxes on Windows do not have any hierarchical structure (there isn't even an owner/child relationship between controls within group boxes). (BTW, there is an NSWindow method, -useOptimizedDrawing:, the documentation for which seems to imply support for overlapping views. Nevertheless, you probably shouldn't use it---it may not work in all cases, and is likely to make your program brittle in the face of any changes made to the frameworks. Additionally, you will almost certainly find that your program runs slower if you do fiddle with this setting.) * 3.2.5 How do I draw ? To draw rectangles quickly, look at NSRectFill(), NSRectFillList(), NSRectFillUsingOperation() et al. For general drawing, use NSBezierPath; in addition to the instance methods, there are a few convenience methods for stroking or filling a single line or rectangle (see e.g. +strokeLineFromPoint:toPoint:, +strokeRect:). To draw more complicated shapes, use the -curveToPoint:controlPoint1:controlPoint2, -lineToPoint:, -moveToPoint:, -appendBezierPath: and -appendBezierPathWith* methods. To draw images, use the methods on NSImage or on the various NS*ImageRep classes. If you just want to copy pixels from one place to another in your view, you can use NSCopyBits(), rather than having to use NSBitmapImageRep. If you want to draw text, there are a couple of convenience methods on NSString and NSAttributedString that will work for small amounts of text. For larger amounts of text, either use an NSTextView (you can make it a subview of the view you're rendering in, set its properties as appropriate and -display it... BTW there's nothing to stop you reusing the same NSTextView to render several pieces of text in your -drawRect: routine, you can just move it, change its properties and -display it again). Alternatively, you can use NSLayoutManager, NSTextStorage and NSTextContainer, without an NSTextView (hint:take a look at NSLayoutManager's -drawGlyphsForGlyphRange:atPoint: method). An alternative (non-Cocoa) way to render text is to use ATSUI (Apple Type Services for Unicode Imaging). You might need to be a little careful when passing coordinates to ATSUI, because it expects fixed-point coordinates, whereas Cocoa uses floating-point values; this could cause trouble if your coordinates get very large for any reason, and it also means that you need to remember to convert them, using FixedToFloat() and FloatToFixed(). However, the trouble of converting coordinates is certainly worthwhile---ATSUI provides access to a large number of advanced typographic features. If you want to render text in Mac OS X, it's certainly worth a look. If you can't find what you want in the Cocoa framework, it is also possible to use Core Graphics functions directly from your Cocoa application; to draw into a Cocoa NSView or NSImage with CoreGraphics, you perform the following steps: 1. Lock focus on the view or image. 2. Obtain a CGContextRef for the Core Graphics context corresponding to your view; you can do this using (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort] 3. Use Core Graphics functions as desired. 4. Unlock focus from your view (or image). You can also create your own Core Graphics context and render directly into that, although doing so is outside of the scope of this FAQ. If you are interested in porting your program to GNUStep, or to other platforms' implementations of the OpenStep or Cocoa frameworks, then remember that Core Graphics and ATSUI are not part of either OpenStep or Cocoa, so any functionality derived this way will need to be rewritten. * 3.2.6 I looked at NSBezierPath, and I can't see how to draw an elliptic arc. NSBezierPath has some instance methods that can draw circular arcs, and one that can draw an axis-aligned oval, but none that will draw an elliptic arc. However, NSBezierPath's contents may be transformed, independently of the view's co-ordinate transform, with the -transformUsingAffineTransform: method, which will allow you to achieve your goal. * 3.2.7 How do I draw a gradient fill? If you're using Jaguar (Mac OS X 10.2) or later, you should use Core Graphics CGShading functions (provided they can achieve the effect you want, of course). One major advantage with using them is that if you are rendering PDF output, they will turn into a PDF gradient fill, rather than a million rectangles, which makes for significant savings in file size. If you need to support pre-10.2 versions of Mac OS X, then your best bet is probably NSRectFillListWithColors() or NSRectFillListWithColorsUsingOperation(). You can use NSDivideRect() to compute the rectangles you need. * 3.2.8 I applied a transform to my view, but now my lines come-out all distorted. Yes. Line widths, patterns and other attributes are geometric rather than cosmetic under Quartz. That is to say, the view transform applies to them just as it applies to the geometry you have specified... so if you stretch the X axis by a factor of two (for example), vertical lines will be twice as thick as horizontal ones. If you don't want a transform to apply to the attributes, then apply it to your geometry rather than to your view. * 3.2.9 My image is upside-down when I render it into my view. Either your view is flipped and your image isn't, or your image is and your view isn't. In any case, use NSImage's -setFlipped: to solve the problem. * 3.2.10 I want my window to be completely transparent, outside of the area that I'm drawing, but when I set the window alpha, I still get Apple's pinstripes showing behind my view. You need to subclass NSWindow and override initWithContentRect to do the following: if ((self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered])) { [self setBackgroundColor: [NSColor clearColor]]; [self setOpaque:NO]; [self setHasShadow:YES]; } The first line removes the window gadgets, which you won't want if you're doing a funny-shaped window. The subsequent lines remove the pinstripes, make the window transparent and enable the shadow (a side-effect being that the shadow region is re-computed). * 3.2.11 I moved my view, but the changes aren't visible on the screen. Views are not windows. If you move one, add it to or remove it from the hierarchy, they don't redraw automatically; you need to tell Cocoa to redraw whichever views are affected using -setNeedsDisplay:. * 3.2.12 My drawing code runs, but I don't see the results immediately. Most likely you have forgotten to do a -setNeedsDisplay:. If you have called -setNeedsDisplay: or display: and the drawing still doesn't appear when you want, consider calling NSGraphicsContext's -flushGraphics, which will cause NSGraphicsContext to flush all of its buffered operations to the screen. * 3.2.13 How can I draw into an NSImage? Use NSImage's -lockFocus and -unlockFocus methods, just as you would with an NSView. * 3.2.14 How do I draw arrows on the ends of an NSBezierPath? Unlike some other operating systems, Mac OS X doesn't provide built-in support for drawing arrowheads on the ends of paths. However, all is not lost; there are at least two approaches that will work: (a) Find the tangent to the end of the path, and use it to rotate another path to the correct angle. This works well for straight lines, but is sub-optimal for curves. or (b) (Harder) Chop the end off the path, rotate it clockwise and anticlockwise about the end, then join the paths together. This works well provided curvature of the path isn't too high near the endpoints. You may have seen arrows drawn like this in diagrams produced with MetaPost. The former approach is pretty easy to implement (hint: you need to use atan2(), and remember that the tangent to the endpoint of a Bezier curve is simply the line passing through the endpoint and the adjacent control point). An example of the latter approach may be found here: http://www.alastairs-place.net/archives/000037.html 3.3 Distributed Objects ----------------------- * 3.3.1 I wrote a program that uses Distributed Objects, but it doesn't seem to work if I run it as a Startup Item. What's going on? Distributed Objects uses Mach ports to implement local inter-process communication. When you run your program as a Startup Item, the port it creates to use DO is in the root port name-space; however, when a user logs-in and runs the other part of your application, the application creates ports in a per-user name-space. If you are trying to communicate from the user half of the application to the Startup Item, you will be fine; if you are trying to use DO in the other direction, however, it will not work because the Startup Item process cannot find the port your application is vending. 3.4 Run-Loops & Event Handling ------------------------------ * 3.4.1 When a user clicks one part of my user-interface, my program may take several seconds to complete the required processing; this makes the beach-ball appear. What can I do to stop it? There are a few different ways to approach this problem, depending on the type of processing you are doing. The simplest is usually just to move the long-running computation to another thread using NSThread's +detachNewThreadSelector:toTarget:withObject: method, then in order to provide status information to the GUI, have the other thread use either Distributed Objects, or NSObject's -performSelectorOnMainThread:withObject:waitUntilDone: method. Another possibility is to use an NSTimer to run small amounts of processing periodically (this might be OK, for example, for processes that the user isn't waiting for... e.g. background spell-checking). One method that is sometimes suggested is to call NSRunLoop's -runUntilDate: method periodically during processing. This isn't ideal because some of the AppKit's processing isn't driven by the run-loop, whilst you are processing your application will behave slightly differently than normal. An alternative if you want to poll for events during a method is to use NSApplication or NSWindow's -nextEventMatchingMask:untilDate:inMode:dequeue: method, together with -sendEvent:, in a loop like so: NSEvent *event; while ((event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate dateWithTimeIntervalSinceNow:0.01] inMode:NSEventTrackingRunLoopMode dequeue:YES])) { [NSApp sendEvent:event]; } You may need to use a different run loop mode, depending on where you invoke this loop. Be aware that doing this is fraught with danger; it is quite possible (unless you take steps to prevent it) that the method you are performing your computation in will be re-entered during the processing of an event, which could cause anything from confusing behaviour through to outright crashes. * 3.4.2 Is there a way to make the run-loop generate events when the status of a file-descriptor changes, like select()? There are a couple of ways of doing this. You can use NSFileHandle's -initWithFileDescriptor: method to obtain an NSFileHandle corresponding to your descriptor, at which point there are a variety of methods on NSFileHandle you can use to perform operations in the background (including waiting for input). Unfortunately, you can't wait for an output notification (so you won't know if you are going to block when you write to the descriptor). Core Foundation also provides a couple of mechanisms, in particular, CFReadStream, CFWriteStream and CFSockets. Strangely, the only CF*Stream function that will create a stream given file descriptors is CFStreamCreatePairWithSocket(), an unfortunate side-effect of which is that CF*Stream then tries to use send() and recv() rather than read() and write(), neither of which work with fds other than sockets. A workaround is to use CF*StreamCreateWithFile, passing-in an NSURL containing "file:/dev/fd/". Obviously this is less than ideal, because it uses another two file descriptors. 3.5 Controls & Cells -------------------- * 3.5.1 I cannot find a standard Cocoa control that does what I want. Are there any third-party controls available? Yes. The following is an undoubtedly incomplete list of third-party controls of which the author is currently aware: Stick Software's Circular Slider http://www.sticksoftware.com/software/CircularSlider.html Omni Group's OmniAppKit (which contains several additional controls, including some very cool sticky palettes) http://www.omnigroup.com/developer/sourcecode/ CHAppKit (two colour-related controls) http://www.concepthouse.com/products/CHAppKit/ AMShapedButton and AMToolTipTableView http://www.harmless.de/cocoa.html Calendar and URLTextView controls http://blackholemedia.com/code/ iTableView (NSTableView with stripes) http://members.iinet.net.au/~tonyarnold/archives/000015.html MiscKit (various additional controls) http://www.misckit.com/index.html MOKit (various) http://mokit.sourceforge.net/index.html UKDistributedView and UKPrefsPanel http://www.zathras.de/programming/cocoa_stuff.php WBSearchTextField, WBTimeControl and WBCalendarControl http://s.sudre.free.fr/Software/DevPotPourri.html Jiiva's Application Builder Collection ($$$, several very nice controls) http://www.jiiva.com/abc/ DisclosableView (including Interface Builder palette) http://www.snoize.com/ Note that some of these controls may become obsolete as Apple adds equivalents to the AppKit framework itself. * 3.5.2 How do I display text *and* an icon in an NSTableView, NSOutlineView or NSMatrix? Create a subclass of NSCell that renders both text and an icon. The *right* way to implement it is such that the -setObjectValue: method on your new cell class accepts an object that contains both the text and the image; you can then implement -tableView:objectValue:forTableColumn:row: in the way Apple/NeXT intended you to. Some people seem to use -tableView:objectValue:forTableColumn:row: as an opportunity to fool with the cell that the table view is about to render; this probably isn't such a good idea, because nowhere in the method does it indicate that the tableview is going to render that column/row immediately after the call. If you want to alter the cell, use the delegate method -tableView:willDisplayCell:forTableColumn:row:, which *is* guaranteed to be called immediately before display. * 3.5.3 How do I constrain what people can type into my text fields? If the NSFormatters available on Interface Builder's palettes don't already do what you need, then you need to create a custom NSFormatter. Editing isn't allowed to finish until -getObjectValue:forString:errorDescription: returns YES. For a more polished approach, implement NSFormatter's -isPartialStringValue: methods. If you have a copy of Cocoa Programming, take a look at Ch. 11 pp. 393--402 for a fairly complete example. * 3.5.4 How do I put an NSProgressIndicator (or some other NSView) into a table view? The basic idea is to add the view as a subview of the NSTableView in the delegate method -tableView:willDisplayCell:forTableColumn:row:. Joar Wingfors has posted some excellent sample code at http://www.stepwise.com/Articles/Technical/2003-12-20.01.html that shows exactly how to do this, and includes not only an example of a progress indicator embedded in an NSTableView, but also some code that implements a rule editor (like the one in Mail.app) using an NSTableView to manage the rows. 3.6 Integrating with the System ------------------------------- * 3.6.1 How do I obtain the icon the Finder would use for a given type of file? Use NSWorkspace's -iconForFileType: method, like so: NSImage *tiffIcon = [[NSWorkspace sharedWorkspace] iconForFileType:@"tiff"]; Note that this method is quite slow, so although it may be fine for one-off use, heavy users may want to build an icon cache. * 3.6.2 How do I launch the user's default ? Again, look at NSWorkspace. There are a variety of methods you can use to achieve whatever you are actually after doing, including: -getInfoForFile:application:type: -openFile: -openFile:withApplication: -openURL: Alternatively, you can use Launch Services (see Technical Note TN2017). * 3.6.3 How do I perform a privileged operation? (e.g. as "root" or an administrator?) Cocoa applications shouldn't really be performing privileged operations directly, because there are too many ways that the flexibility of the Objective-C language and the Cocoa frameworks can be exploited to subvert an application that gains superuser privileges. Either have your program execute a setuid tool (preferably written in C by someone that understands how to write secure C programs), or, if password authentication is appropriate, use Authorization Services. See http://developer.apple.com/documentation/Security/Conceptual/authorization_concepts/index.html and http://developer.apple.com/documentation/Security/Reference/authorization_ref/index.html * 3.6.4 How do I get that password box to appear? The password box is displayed automatically by the security server in response to requests made by applications through Authorization Services. See 3.6.3 for more information. 3.7 Miscellaneous --------------- * 3.7.1 What is NSNull and why am I getting one? NSNull is used when placing null values into collection objects, as the Cocoa collection objects do not allow you to store "nil" as a value. It is quite a common requirement to check that an object pointer is not nil; to do this and take account of the possibility of an NSNull, the test should look like this: if (!object || object == [NSNull null]) Note that there is only ever a single instance of NSNull in the system. * 3.7.2 How do I do file operations? Should I use NSFileWrapper? No. NSFileWrapper brings the entire file or directory into memory, which is not normally what you want to do. Instead, use NSFileManager, NSFileHandle or the C runtime or BSD functions. Remember that if you are using the C or BSD functions, you should convert file and folder names contained in NSStrings using the -fileSystemRepresentation method and not the -cString or -UTF8String methods. * 3.7.3 How do I do networking? Should I use NSSocketPort or NSPort? No. The NSPort classes are for Distributed Objects. Either use the BSD sockets functions (which are documented in "man 2 socket" as well as in any good book on TCP/IP), or use Core Foundation's CFSocket and/or CFNetwork services (see http://developer.apple.com/documentation/CoreFoundation/Networking-date.html for more information). If you choose to use the BSD functions, you may find it convenient to combine them with either NSFileHandle or CFStream... see question 3.4.2. It is also worth saying that there are several third-party frameworks available that provide socket-based communication; see http://cocoadev.com/index.pl?SocketClasses for a list. * 3.7.4 I created an object in Interface Builder, and its outlets don't seem to be connected when my program is running. I've double-checked, and they're definitely connected in IB. What's going on? You have probably defined a method called "set:", but that doesn't actually set the outlet member variable. The reason this causes trouble is that the objects in a nib file are archived, and the un-archiving process looks for accessor methods when trying to wire-up the outlets. See the documentation for NSNibConnector's -establishConnection function, as well as the NSKeyValueCoding protocol. * 3.7.5 How do I use a class that might not be available at run-time? (for example because it is only available on newer releases of Mac OS X)? To use a class that may or may not be there, you can use the features of the Objective-C run-time to obtain a pointer to the Class object, then use that to get an instance of the class you want. For example: Class shadowClass = objc_lookUpClass("NSShadow"); id shadowInstance = [[shadowClass alloc] init]; or Class shadowClass = NSClassFromString(@"NSShadow"); id shadowInstance = [[shadowClass alloc] init]; In the example above, shadowClass will be nil if NSShadow cannot be found (hence shadowInstance will also be nil). If you want similar functionality for functions or variables (as opposed to Objective-C classes), you will need to look at Tech Note 2064, here: http://developer.apple.com/technotes/tn2002/tn2064.html 3.8 Portability --------------- * 3.8.1 Is code written with Cocoa portable? Yes, and no. In the past, the Application and Foundation Kit have been available on a number of different platforms, including NeXTStep, Sun, HP and Windows. Unfortunately, Apple have discontinued support for Sun, HP and Windows, and we are left with Mac OS X (which is a re-hash of NeXTStep). There is good news as well though; there is a GNU Project effort, called GNUStep, to implement the OpenStep specification on top of X11. In addition to X11, they are working on back-ends for other operating systems, although the one most people are likely to be interested in, Windows, is in a "pre-alpha" state (and has been for some time) as far as the GUI implementation is concerned. GNUStep developers are making some effort to track Apple's changes, but it is low priority for them, so for example they do not have NSDrawer or NSToolbar (as of 31 Aug 2003). * 3.8.2 Can I use Core Graphics or Core Foundation with GNUStep? No. * 3.8.3 Can I use Carbon, Quicktime or other Apple APIs with GNUStep? No. * 3.8.4 Can I use NIB files with GNUStep? Not exactly. GNUStep uses another tool called Gorm, mostly because the NIB format isn't officially documented. You can convert NIB files to Gorm files using a tool mentioned in the GNUStep FAQ---see http://www.gnustep.org/information/faq_1.html#SEC8 * 3.8.5 Can I read archived data saved by Cocoa using GNUStep? Unfortunately not. Apple haven't documented the format. * 3.8.6 Can I used Distributed Objects to communicate between Cocoa and GNUStep? See 3.8.5. * 3.8.7 Where can I get GNUStep? Where can I find more information about GNUStep? There is lots of information at http://www.gnustep.org, as well as source code, including a few complete applications. * 3.8.8 I wish Apple would bring-back YellowBox for Windows. In which case you should probably report it as a bug using Bug Reporter, at http://bugreport.apple.com ------------------------------ Subject: 4. Miscellaneous ========================= * 4.1.1 Should I use an installer? It's far better if possible if your application is just a single file that they can drag into their Applications folder (or wherever else they want to put it). One possible option, if you need to place files in particular places in the file system, is to put them inside the application bundle and have the application itself copy them into the required locations when it is first launched. (Obviously, the application might need to ask for an Administrator password in order to do this). In addition, many of the installation packages currently available for Mac OS X have problems of one sort or another, ranging from problems dealing with resource forks or file time-stamps through to outright dangerous behaviour like replacing symlinks with actual directories. If you are going to use an installer, it should probably be the Apple package installer that is built-in to Mac OS X... however, if you are using Package Maker, be aware of the following problems: i) Package Maker uses Pax in a manner that causes symbolic links to be replaced; therefore *DO NOT* set the "Default Location" to / with Package Maker packages... if you try to install something into e.g. /etc, you will end-up with a machine that will not boot. You can work around this problem by creating multiple packages, one per directory, and setting the "Default Location" to the actual directory you want to install into, then creating a .mpkg containing the individual packages. ii) Package Maker helpfully allows you to write scripts that are run at various points during your installation. These scripts *must* work properly in the presence of filenames containing spaces and other unusual characters; Macintosh users expect to be able to name their files and folders however they please, and will not be impressed if you destroy their data because of a bug in your script related to an unusual filename. (Even Apple have fallen foul of this problem). Another issue with installers is that there is currently no user interface for an un-installer. If your application explodes all over the user's filesystem, they might not be very happy when they want to remove it. * 4.1.2 My application used to compile fine, but now I get syntax errors on lines where I've declared variables in the middle of a function/block. What's wrong? You have either installed the GCC 3.3 developer tools update or Xcode onto a machine that already has Project Builder. Project Builder becomes confused when this happens, and runs GCC 2.95 even if GCC 3.1 is selected in the build options; the release notes for the developer tools update give the following workaround: i) Set the default compiler back to GCC 3.1 using sudo gcc_select 3.1 from Terminal. ii) For every project you want to build with 3.3, add the following settings to your target's Expert View Settings: GCC_VERSION=3.3 CC=gcc-3.3 CPLUSPLUS=g++-3.3 The reason it's happening is that declaring variables in the middle of code is a C99 feature, and GCC 2.95 didn't have support for C99. * 4.1.3 The documentation is really hard to use. How can I search or browse it more easily? Get one of the following documentation browser programs: AppKiDo http://homepage.mac.com/aglee/downloads/ Cocoa Browser http://homepage2.nifty.com/hoshi-takanori/cocoa-browser/ Docoa Browser http://www.iwascoding.com/DocoaBrowser/ * 4.1.4 Why does my program crash? How should I know? ;-) Seriously though, Project Builder has an integrated debugger (or, if you're more at home with the command line, you can run GDB from there). Use it! Please don't post "why does this crash?" questions to the list without at least having a go with the debugger first... chances are you will be able to figure-out what is wrong yourself. A few common mistakes that cause crashes: - Releasing objects that are already released. - Releasing objects that are already autoreleased (this is harder to debug because the crash happens later). - Using C strings where you should have passed an NSString (usually this is because you have missed-out an @ character before the open-quote). - Using the %@ format specified in NSLog() for something that is not an object. - Sending a message through an uninitialised object pointer. Also remember that if your program crashes with an exception (or assertion failure), the text in the Terminal or Run window will tell you what the exception means. It is generally best to assume that if you get an exception from the framework, it is you that has made a mistake (e.g. if you see an assertion failure like Assertion failed: index >= 0 && index <= [object numElements] you should assume that you have passed an out-of-range index somehow, rather than jumping to the conclusion that there must be a negative number of elements in the object). One final hint: it is often useful to set a breakpoint on [NSException raise], which will allow you to see where exceptions are thrown, as the debugger will then stop your program in a more helpful place when an Objective C exception is raised. * 4.1.5 My method never gets called, but I'm sure I followed the documentation to the letter. You probably have a typo in your method name; check the spelling very carefully, especially if you created a selector value... it's very easy to forget a trailing : character and write @selector(doSomething) rather than @selector(doSomething:). * 4.1.6 My program needs to look exactly like the Windows version to avoid confusing my users. How do I implement ? No, it doesn't. Your program should integrate with Mac OS X and look like a *native* application. Users with Macs will be confused if you make your program look like a Windows program. There are *very* few programs for which the argument that they already have a user interface is a factor. * 4.1.7 Please could someone give me some programming-style pointers. *PLEASE* don't post messages like this to the list. Everyone will give you their own take on good coding style, and it is usually fairly controversial so we end-up with a coding-style war. Apple publish some coding guidelines at http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/index.html and there a couple of articles at Stepwise, including Accessor methods revisited - mmalcolm crawford http://www.stepwise.com/Articles/Technical/2002-06-11.01.html and Conventions: What's in a name? - Erik Buck http://www.stepwise.com/Articles/Technical/2002-10-13.01.html that you should probably read if you're using Cocoa, otherwise there are a number of books on good coding style, as well as a lot of widely differing guidelines. Use an Internet search engine and type "coding style". There are a few basics that just about everyone agrees on, which are: - Your variables and functions should have readable names. - Your source files should have readable names. - You should separate things into interface and implementation. - Your functions shouldn't be too long. - You should space and comment your code. - You should aim for code that is easy to understand. The exact details of how you go about doing all of these things are where the disagreements start ;-) * 4.1.8 I'd like to use libXYZ in my program, but I can't get it to compile. Getting third-party libraries to build successfully can be troublesome, although it is often easier than it looks. This question is too complicated to provide a general answer here, but see http://fink.sourceforge.net/doc/porting/index.php and http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/compiling/index.html for more information on porting software to Mac OS X. It is also a good idea to check that there isn't already a pre-built version for Mac OS X. * 4.1.9 How do I use Altivec/Velocity Engine? If you are just writing a simple Cocoa application, you don't need to do anything... Core Graphics will already use it whenever possible to accelerate image scaling, compositing and other operations. If, however, you want to do some really high performance DSP or something, read on. Apple provide a framework called vecLib that incorporates DSP, BLAS, bignum and other functionality, and automatically uses Altivec if it exists on the machine on which your program is running. See http://developer.apple.com/hardware/ve/vector_libraries.html If you really want to do something fancy, specify the -faltivec compiler switch, which will allow you to use vector types from C or Objective-C (without using assembler). See http://developer.apple.com/hardware/ve/tutorial.html Apple's Velocity Engine home page is at http://developer.apple.com/hardware/ve/ * 4.1.10 I think I found a spelling mistake in the FAQ. Quite probably, although please remember that there are two variants of English in common use... American English and British or International English. So, for example, some of us write "colour" rather than "color" or use 's' in words like "categorise" where you might expect a 'z'. There are also words that speakers of one or other variant may not understand (e.g. a "fortnight" is 14 days to a speaker of British English, but apparently isn't used in American English); if you spot one of these, please tell the maintainer, who will be pleased to substitute a suitable alternative. * 4.1.11 Why is this FAQ plain text... wouldn't HTML look nicer? Possibly. Plain text has several advantages though; it is simpler and is guaranteed to work properly whatever you view it with, which makes it easier to add new FAQs to the document. Maybe there will be an HTML version at some point, just not yet. * 4.1.12 How does Cocoa compare with ? Again, an interesting question, however generally very difficult to answer thoroughly, as to do so you would need to be an expert in both toolkits, and even then, the answer is rather subjective. If you must ask this question, please do not ask on the Cocoa-dev list; there are other, more appropriate forums for discussing the merits of Cocoa vs. some other toolkit (e.g. Omni's macosx-dev list or the various Macintosh programming newsgroups). In addition, when asking questions like this, please try to be open-minded... it takes a lot of time and effort for people to contribute meaningfully to a discussion as complex as this, and if you come at it with a pre-determined opinion you are wasting their time as well as your own. The opinion of the Cocoa developer community is that Cocoa *is* better than most other GUI toolkits available today, for a variety of reasons but most of all because the design of the frameworks is of a very high standard. Unlike many other toolkits, which are often an OO wrapper around an existing C interface, Cocoa has been designed using OO principles from the ground up. Another distinguishing feature of Cocoa is the ease with which behaviour can be customised *without* resorting to subclassing; Cocoa provides copious support for delegation, both directly and through notifications. * 4.1.13 My program builds and runs fine, but when I try to run it from the Finder or give it to my friends/colleagues, it quits on launch. I'm using Xcode, and it used to work fine with Project Builder. You are building using the Development build style and have ZeroLink enabled. Build your application using the Deployment build style before distributing it. ZeroLinked applications will only run from within Xcode itself. * 4.1.14 Is there a list of assigned Rendezvous service names? Yes, there is an unofficial list here: http://www.dns-sd.org/ServiceNames.html You do need to remember that all of the IANA service names are reserved for use by the existing protocols that claimed them. There is a list here: http://www.iana.org/assignments/port-numbers * 4.1.15 Xcode says my build has failed but I don't see any error messages, or I see a message about undefined symbols but it doesn't say which. How do I get a better description of what is wrong? The first thing to do is to click the tiny button that looks like a text document at the bottom left of the Build Errors and Warnings window. This will display the raw output from the build process. (In newer versions of Xcode, you can also drag the horizontal separator at the bottom of the window.) If you can see a line in the top part of the window that has an error logo next to it, then you can click that to select the associated lines of output in the bottom pane (the raw output part). To debug undefined symbol problems, you may find it helpful to look in the raw output after the line that says that there are undefined symbols, where you will find a list of (possibly name-mangled) symbols. To demangle C++ (or Java) symbols so that you can read them more easily, you may find it useful to look at the "c++filt" program (try typing "man c++filt" from a Terminal prompt, or invoke the manual page from the help menu in Xcode). For instance, entering c++filt _ZSt9terminatev _ZnwmRKSt9nothrow_t will display std::terminate() operator new(unsigned long, std::nothrow_t const&) (Note that you may have to remove a leading underscore from the symbol name to make this work.) ------------------------------ Subject: 5. Related Documents ============================= * 5.1 Apple Apple have a large number of developer-oriented resources available through their main developer site. In particular, if you are developing polished applications for Mac OS X, you should make sure you have read the Aqua Human Interface Guidelines as well as the Mac OS X system overview; both of these documents contain essential information on how your application should operate when running under Mac OS X. Developer site http://developer.apple.com Developer documentation http://developer.apple.com/documentation/ The Objective-C Programming Language http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/index.html Aqua Human Interface Guidelines http://developer.apple.com/documentation/UserExperience/Conceptual/AquaHIGuidelines/index.html Cocoa Coding Guidelines http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/index.html Cocoa documentation http://developer.apple.com/documentation/Cocoa/Cocoa.html Core Foundation documentation http://developer.apple.com/documentation/CoreFoundation/CoreFoundation.html Quartz (Core Graphics) documentation http://developer.apple.com/documentation/GraphicsImaging/GraphicsImaging.html Mailing lists http://www.lists.apple.com/mailman/listinfo * 5.2 Cocoa-dev list archives http://cocoa.mamasam.com * 5.3 Omni Group Omni Group have very kindly provided the source code to the frameworks that they use to implement their applications, as well as hosting a number of mailing lists. If you haven't looked at Omni's site, you probably should. Omni Group's developer resources http://www.omnigroup.com/developer/ Source code http://www.omnigroup.com/developer/sourcecode/ Game development http://www.omnigroup.com/developer/gamedevelopment/ Mailing lists http://www.omnigroup.com/developer/mailinglists/ * 5.4 Stepwise http://www.stepwise.com Stepwise is a Cocoa/NeXT/OpenStep/WebObjects news and information site; it has a large number of articles relating to Cocoa and WebObjects development, and is maintained by Scott Anguish, one of the authors of the Cocoa Programming book. * 5.5 comp.lang.objective-c FAQ http://www.faqs.org/faqs/computer-lang/Objective-C/faq/ An FAQ dedicated to Objective-C; doesn't carry information specifically about Cocoa, but certainly worth a look. * 5.6 comp.lang.c FAQ http://www.eskimo.com/~scs/C-faq/top.html This very comprehensive FAQ covers the K&R and ANSI C programming languages; every C, Objective-C and C++ programmer should read this. * 5.7 GNUStep http://www.gnustep.org A Free Software implementation of the OpenStep API, GNUStep is partially compatible with Cocoa, and can be a good way of porting your program to other flavours of UN*X. GNUStep is also being ported to Windows, although the Windows port is in the very early stages at the moment. * 5.8 Usenet newsgroups comp.sys.next.programmer comp.lang.objective-c comp.lang.c comp.sys.mac.programmer.* You will need a newsreader to read Usenet newsgroups. When posting to newsgroups, be aware that: (i) You should read any associated FAQ *before* posting. (ii) You should post messages only to appropriate newsgroups. For example, you will trigger complaints if you post a message about Macintosh programming to comp.lang.c, or a message about C++ to comp.lang.objective-c. Cross-posting (posting a message to more than one group) is generally frowned upon, unless you have a good reason. (iii) Like any public forum, there are rules of acceptable behaviour; see RFC1855 for some general advice on what to do and what not to do. You can find a copy at http://www.ietf.org/rfc/rfc1855.txt?number=1855 (iv) Some newsgroups have a "moderated" variant, which is filtered by a moderator or a group of moderators. These are often more useful than unmoderated groups, as the level of noise is lower. * 5.9 CocoaDev Wiki http://www.cocoadev.com This is a Wiki. For those that don't know what one of those is, the basic idea is that it is a set of hyperlinked documents that may be edited by a large group of people (in the case of CocoaDev, anybody can edit the majority of the pages). CocoaDev tends to contain hints and tips, although there are complete articles on a few topics. A fair number of Cocoa developers have added their own page, describing who they are and what they do. * 5.10 MacOSX Guru http://www.macosxguru.net This site is dedicated to short(ish) FAQ-type questions; like CocoaDev, anyone can contribute, but the presentation is quite different. * 5.11 Cocoa Dev Central http://cocoadevcentral.com Cocoa Dev Central is a nicely presented site containing fair-sized articles and tutorials on key Cocoa topics. Like other Cocoa-related sites, anybody can contribute.