Jump to content

***** For Programmers: Getting Answers ******


Recommended Posts

Posted

Question Guy and Answer Man will be helping us out by illustrating the principles in the guide. QGuy and AMan will have simulated conversations showing the right and wrong way to get good answers quickly. The conversations are made up, but every single one of them is taken directly from situations I've seen.
Explain what doesn't work
You'd think this would be obvious, but it's not. Many people will ask about general technique or something they feel is simpler and related instead of just saying what is going wrong. If you think it's a problem with general technique, then ask that too, but always tell people what isn't working for you.
Bad question:

QGuy: how do I compile an app on 10.4 that works on 10.3?
AMan: set up the SDK like so: ...
QGuy: is there any other way?
AMan: I don't understand what you mean
QGuy: well, my app crashes on launch on 10.3
AMan: ...
Good question:

QGuy: my app crashes on 10.3 but works fine on 10.4, how do I discover the problem? is this a problem with how I set up my build?
AMan: your build setup shouldn't matter, you're probably linking against something that doesn't exist on 10.3. look at the Console output after the crash to see what it is
What's going wrong is, "my application crashes on launch on 10.3", but this doesn't even get mentioned until several rounds into the question/answer process, and after much time wasted on both sides. Answer Man's explanation of SDKs was completely pointless because Question Guy already knew about it. Question Guy lost time by turning Answer Man onto an irrelevant path instead of stating his problem at the start.
By stating exactly what is going wrong right away, Question Guy got a useful answer from Answer Man instantly.
Provide everything up-front
Making people fish for information wastes your time. Give as much background information in your original question as you can.
Bad question:

QGuy: how do I append to a string?
AMan: use stringByAppendingString:
QGuy: well, I don't want to create a new object
AMan: then use NSMutableString and appendString:
QGuy: but I'm using C, not ObjC
AMan: argh, why didn't you say so? use strcat
QGuy: what if I have a CFString?
AMan: gah! use CFStringAppend
QGuy: but that doesn't work, I need to append a char *
AMan: screw this
Good question:

QGuy: how do I append a char * to a CFString? The stuff I'm finding only works with CFMutableString
AMan: that's your only choice, you'll have to make a mutable copy, then use CFStringAppendCString
Under-specifying your question doesn't save you any time (you'll have to say it all eventually anyway) and makes people less likely to reply to you, both now and in the future.
You might be afraid of saying too much. Don't be. It's far better to be over-specific than under-specific, as it's much easier for somebody to ignore the extra details than it is to ask you for the missing ones. When in doubt, say, "I'm not sure if it's relevant, but I'm doing...."
Post your code
This doesn't apply to big conceptual questions, of course, but for everything else it's essential. Never describe your general approach to a problem without posting the code behind it, because the code is what counts, and translating everything through English tends to change it beyond recognition.
Bad question:

QGuy: when I create an NSString from UTF-8 data it fails, why?
AMan: post your code
QGuy: I don't think it's a code problem
AMan: screw this
Bad question #2:

QGuy: if I subclass NSMatrix then nothing appears on the screen, but using a plain NSMatrix works, why?
AMan: how the heck should I know?
Bad question #3:

QGuy: when I create an NSString from UTF-8 data it fails, why?
AMan: post your code
QGuy: I don't have the code with me, but I'm doing something like char *utf8str = ...; [utf8str stringWithUTF8String]
AMan: you can't send a message to a char *, and there's no such method as stringWithUTF8String with no parameters, try ...
...the next day...
QGuy: I figured out the problem, I was actually using stringWithCString:
AMan: aarrgghh!
Good question:

QGuy: when I create an NSString from UTF-8 data using char *utf8str = ...; [NSString stringWithCString:utf8str] it fails, why?
AMan: because stringWithCString: doesn't expect UTF-8, use stringWithUTF8String
Asking for code takes time and effort, and you can hasten the answer by providing it right away. If you don't know whether it's relevant or not, post it anyway. Never paraphrase or type from memory. Even when done with the best of intentions, you'll introduce subtle or blatant errors in your code, and the people you're talking to will be solving a problem completely different from what you actually have.
(On IRC, don't forget to use a pastebot. Pasting your code directly into the channel is considered rude if it's more than a line or so.)
Do your research beforehand
While it can be a good idea to ping a friend or two about a problem as soon as you run into it, asking strangers should be near your last resort. Do as much as you can to research the problem and solve it on your own before you do so. This will help you get an answer by letting you pose a much more informed question. The more you know about the topic, the better chance of asking what you need.
Bad question:

QGuy: how do I create a thread?
AMan: rtfm!
Good question:

QGuy: I read the NSThread docs but how can make it call a method with an int parameter?
AMan: make a new method that takes an NSNumber and just calls the other method with its intValue
In the first version, Question Guy didn't get a very useful response. The second version's response was much more useful, because Question Guy read about the topic before he asked his question.
Question Guy also made the smart move of detailing what he researched. You're much less likely to get the useless rtfm! if you tell everybody which fine manuals you've already read.
Do your research during
Your work doesn't stop once you ask the first question. When presented with an unfamiliar piece of advice, research it before you ask about it. Even just sticking the unfamiliar term into Google can help a lot.
Bad question:

QGuy: how can I get a directory listing?
AMan: use NSFileManager
QGuy: what's NSFileManager?
AMan: rtfm!
Good question:

QGuy: how can I get a directory listing?
AMan: use NSFileManager
...QGuy puts NSFileManager into Google...
QGuy: ok, thanks... is there any way to make it only give me results whose names begin with "tty"?
AMan: you can get all of the results, then filter them using NSPredicate by doing...
Researching your followup questions as well as your original question will get you more useful replies.
Do your research afterwards
I bet you saw this one coming. After you get advice and depart, you should do as much research as you can, before coming back and asking questions about the advice.
Bad question:

QGuy: how can I get a directory listing?
AMan: use NSFileManager
...QGuy departs...later:
QGuy: how do I use NSFileManager?
AMan: rtfm!
Good question:

QGuy: how can I get a directory listing?
AMan: use NSFileManager!
...QGuy departs...the next day:
QGuy: when I use NSFileManager to list the contents of /, I get "Applications" instead of the translated name I see in the Finder, why does it do that and how do I duplicate Finder's behavior?
AMan: localized names don't exist in the filesystem, but you can use...
As before, doing your research makes for better answers.
Don't post the same question repeatedly
This especially applies to forums and mailing lists, but it applies to IRC too. Unless your problem is highly complicated, many people will be able to help you. Chances are one of those people saw your question the first time. If nobody answers, do more research, try to produce a small test case or at least narrow the problem down, and come back in a day or two with more information.
Bad question:

QGuy: my custom NSMatrix subclass doesn't draw, help?
...crickets...the next day:
QGuy: my custom NSMatrix subclass doesn't draw, help?
...crickets...the next day:
QGuy: my custom NSMatrix subclass doesn't draw, help?
Good question:

QGuy: my custom NSMatrix subclass doesn't draw, help?
...crickets...the next day:
QGuy: my custom NSMatrix subclass doesn't draw, I created a simple test project that exhibits the behavior, you can download it at [url=http://blah]http://blah[/url], anybody know what's going on?
AMan: don't override drawRect:
If nobody could answer your question the first time, they probably can't want to answer it the second time either. Use the time you spend waiting for an answer to work on the problem yourself. Even if you have no hope of solving it, you can produce something and gather information that will help others solve it.
Follow up after you get an answer
You should always reply to people who give advice, even if you understand it and it works perfectly and you don't need any more information.
Bad question:

QGuy: my program crashes with an EXC_BAD_ACCESS when I do [obj release], what's going on?
AMan: you're probably over-releasing, try using NSZombieEnabled
...later...
QGuy: my program crashes in some sort of notification callback, how can I debug that?
AMan: wait, did you solve your [obj release] crash?
...later...
QGuy: my program gives me an error saying NSString doesn't respond to setObject:forKey:, how do I debug that?
AMan: screw this
Better question:

QGuy: my program crashes with an EXC_BAD_ACCESS when I do [obj release], what's going on?
AMan: you're probably over-releasing, try using NSZombieEnabled
QGuy: ok, thanks
...later...
QGuy: I found my over-release problem from before, but now my program crashes in __CFXNotificationPost, how can I debug that?
AMan: make sure you remove yourself as an observer from the NSNotificationCenter in your -dealloc method
QGuy: oops, thanks
...later...
QGuy: ok, got the notification crasher fixed, but now my program gives me an error saying "-[NSCFString setObject:forKey:]: selector not recognized", how do I debug that?
AMan: that could be due to another over-release bug, or just a confusion of types where you're treating a string like a dictionary
QGuy: ok, I'll take a look, thanks
Unless you're paying for help (in which case you can probably ignore this entire page, and the person you're paying will just charge more), the people who are answering your questions are doing it for free. Like a cute puppy who sits on command, you need to reward them when they do what you want.
The second conversation is labeled "better" instead of "good" because it probably violates rule #2. The basic answers to these questions should exist in the conceptual documentation, which can then be used to ask a better question and get a better answer. But I couldn't think of a better example.
For more complex questions, follow up with how you finally solved it and which advice you used. This not only provides a powerful reward to the people who provided it, but it allows other people to learn from your example.
Treat the list like people
Many conversations I see indicate a subtle, buried belief that the list or chat is some kind of answer machine, and the key to obtaining a good response is to hunt around until the precise required format for the question is found.
Bad question:

QGuy: how do I append to an NSString?
AMan: read the NSString docs, search for "append"
QGuy: I'm new to Cocoa and I want to append to an NSString, how do I do that?
AMan: hello? read what I said above
QGuy: I'm on 10.4.7 using Xcode 2.3, I don't know much about Cocoa, how do I append to an NSString?
AMan: ...
Good question:

QGuy: how do I append to an NSString?
AMan: read the NSString docs, search for "append"
QGuy: doh, sorry, I forgot to mention that I want to append a C string
AMan: in that case, make an NSString from the C string, then append that, or use %s with stringByAppendingFormat:
It's not a game, you're talking to real live people. Treat them just as you would treat people you're talking to face-to-face, and you'll get much better results.
Always consider the answer
Sometimes a real moron will reply to you, and sometimes you'll get a smart guy who's having a bad day or who didn't correctly read your question. However, most of the time you'll be talking to people who know more about the subject at hand than you do (that's why you came to them for help in the first place, remember). As such, it pays to at least entertain the possibility that they know what they're talking about.
Bad question:

QGuy: how can I memory-map a file using Cocoa?
AMan: NSData
QGuy: please read my question again, I want to memory-map a file
AMan: ...
Better question:

QGuy: how can I memory-map a file using Cocoa?
AMan: NSData
QGuy: huh? how is that related to memory-mapping a file?
AMan: NSData has initializers that let you create one by memory-mapping a file
Good question:

QGuy: how can I memory-map a file using Cocoa?
AMan: NSData
QGuy: got it, thanks!
If the other person's answer really was correct, then you gain a lot of time if you started with the assumption that it was. If you assume it's wrong, you'll either have to wait for the other person to correct you, or if you're unlucky he won't even bother and you won't have an answer. Even if the answer is wrong, you're more likely to get a correct answer if you're gentle when pointing out the wrongness.
Having your solutions get rejected by the person asking the question is frustrating. Frustrated people are less likely to answer your questions. Be good to them, and they'll be good to you.
Note for mailing lists: unlike ephemeral media like IRC, mailing lists are typically archived and searchable. When you find a solution, post it! That way, when you forget about how you did this months later and search the list for an answer, you can see how you actually solved it before.

[url=http://mikeash.com/getting_answers.html]http://mikeash.com/getting_answers.html[/url]

×
×
  • Create New...