views:

838

answers:

5

Newbie question. Looking at arrays (ie: dynamically sized) this works:

NSArray *array;
array = [NSArray arrayWithObjects:
     @"one", @"two", nil];

This does not:

array = [NSArray arrayWithObjects:
     1, 2, nil];

Ok, I get it. This works:

array = [NSArray arrayWithObjects:
     [NSNumber numberWithInt:1], [NSNumber numberWithInt:2], nil];

Its sorta less "on the fly" as C++ / Java. I see the same thing with the init examples I'm reading. For example:

// pseudo objc example
MyVar v = [MyVar init];  // blank
[v setSomething];
[v setSomethingElse];
// use v down here

In C++/Java I'd do:

MyVar v = new MyVar("foo", "bar", "baz", "quux");

And I'd know that v is ready to go by default. Is there a spirit of ObjC that I should not fight? Should I just expect to write more lines and less "one-liners"?

A: 

Yeah, Objective-C is pretty verbose, so you're going to need to get used to that.

The MyVar init case is not quite right; you generally need to do a [[MyVar alloc] init] or a [MyVar new]. And in many cases, there are init variants that take arguments, like

MyVar v = [[MyVar alloc] initWithSomething: "foo" somethingElse: "bar"];

If you want something less verbose, where you can get more one liners in, you might want to look into MacRuby, which is a binding between Ruby and Objective-C that gives you access to all of the Cocoa APIs but with a much more compact, high level syntax (and you can go even more compact still with HotCocoa. Of course, there is a bit of a performance penalty using MacRuby, so if you're doing a high performance game it might not be ideal to write your drawing loop in RubyCocoa, but its fine for the vast majority of applications.

Brian Campbell
Thanks for the insight Brian.
milkfilk
+4  A: 

In Objective-C, the "init" method is just a method. Unlike Java or C++ whose constructors are different than other methods. So you can define your own init methods that behave like C++ or Java constructors. For example, you could define an init method that takes several parameters. It might look something like this.

MyVar* v = [[MyVar alloc] initWithName:@"foo" andTitle:@"bar"];
// do something with v
[v release];

Common practice is to simply create new methods that perform object initialization, and prefix the method name with "init" for clarity and consistency.

Whisty
Objective-C style does eschew the use of the word "and" in method names. That would normally be initWithName:title:.
Chuck
+1  A: 

You can write constructors that take named parameters to get it down to one line:

MyVar *v = [[MyVar alloc] initWithFoo:@"foo" bar:@"bar" baz:@"baz" quux:@"quux"];
dbarker
+2  A: 

What you get with Objective-C's verbosity is greater readability.

Sure, while you're writing code, it might be easy to knock up something like you wrote

MyRect rect = new MyRect(1.0, 1.0, 3.0 3.0);

But when you, or more likely someone else, comes to maintain your code then I would argue that this is much easier to read:

MyRect *rect = [[MyRect alloc] initWithX:1.0 Y:1.0 width:3.0 height:3.0];

And in these days of smart editors it isn't that much harder to write.

Abizern
+2  A: 

NSArray, its modifiable variant NSMutableArray, and all collection structures (NSDictionary, NSSet) are made for storing objects. This is why you see [NSNumber numberWithInt:1] instead of simply 1.

For strings, note that an Objective-c string (like @"one", including leading @) is an object of type NSString, whereas a C string (like "one", without @) is not an object.

If you want the simplicity of storing simple values in arrays, don't forget that Objective-C is a superset of C. This means that you can use a declaration like:

int array[] = { 1, 2, 3 };
mouviciel