Translate ASOC into Objective-C?

Ok, so I tried this without success:

self.classNames = [NSMutableArray initWithArray: [theDictionary allKeys] copyItems : true];

Xcode says: No known class method with such name. I know, but why can I not use an instance method?

Now take time to look back at ASOC and consider that

set my classNames to theDictionary’s allKeys()

simply works-- elements of the AS list are mutable, no worries, and the code is much more readable, is not it?

you forgot the alloc

self.classNames = [[NSMutableArray alloc] initWithArray: [theDictionary allKeys] copyItems : YES];

but copying the items doesn’t make them mutable, only new objects are created.

The mutable issue is:

If you create an mutable array with [NSMutableArray arrayWithArray:someArray], the new array is mutable that means you can add, insert and remove items.
If one of the items in the array is an dictionary for example and this dictionary was mutable in someArray, it’s now immutable.

Ok, and now. what the heck is this:

@synthesize gSegControl = _gSegControl;

a) is the property gSegControl “renamed” _gSegControl? And why?
b) what’s the difference between self.gSegControl and _gSegControl
c) which one should I use? which one should I not? :rolleyes:

Thanks!

first of all

mine too, gSegControl is not very readable :wink:

there is an instance variable _gSegControl and a property gSegControl.
An instance variable can be synthesized with a different name

the dot syntax self. uses the synthesized accessor method, the second case accesses the instance variable directly.

for key value observing/coding use the property with self. syntax, otherwise the instance variable is sufficient.

Normally it’s not necessary to synthesize a property with a different name,
if you don’t know the purpose it confuses more than it helps

Ok. so let’s say I want to reproduce :

script myAppDelegate
property parent : class “NSObject”
property theSegmentedControl : missing value – outlet
property theArrayController : missing value – outlet
property theDictionary : missing value – no outlet, just a property to be accessed by all methods
property currentClass : missing value – no outlet, just property

I should declare, in the .h file :

@interface myAppDelegate : NSObject

@property (assign) IBOutlet NSSegmentedControl *theSegmentedControl;
@property (assign) IBOutlet NSArrayController *theArrayController;
@property (assign) NSMutableDictionary *theDictionary;
@property (assign) NSString *currentClass;

@end

and then, in the .m file :

@implementation myAppDelegate

@synthesize theArrayController;
@synthesize theSegmentedControl;
@synthesize theDictionary;
@synthesize currentClass;

And now for coding:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Classes" ofType:@"plist"];

theDictionary = [[NSMutableDictionary alloc] dictionaryWithContentsOfFile: filePath];

// NO: gives no visible @interface for 'NSMutableDictionary declares the selector ‘dictionaryWithContentsOfFile’

theDictionary = [NSMutableDictionary dictionaryWithContentsOfFile: filePath];

// NO: gives EXC_BAD_ACCESS – Bang!

self.theDictionary = [[NSMutableDictionary alloc] dictionaryWithContentsOfFile: filePath];

// NO: gives error no visible @interface.

And of course self.theDictionary = [NSMutableDictionary dictionaryWithContentsOfFile: filePath]; bangs too.

Remember? I’m trying to translate only a working property theDictionary : missing value! Maybe I’m too stupid but I just can’t see yet the advantages of Objective-C. How long did I read on another post? One year? :frowning:

At one stage, using retain generated an error at compile time. The advice was clearly to use assign (or copy). But the latest I can find is a message from one of the runtime engineers: “(retain) and (assign) are identical under GC.”

But dealloc has never been supported under GC.

You don’t use alloc unless the method that follows starts with init. dictionaryWithContentsOfFile: has the alloc built in.

You should use self.theDictionary although I don’t think what you did should give you a bad access error. Did you try logging filePath to see if it’s giving you a good path?

Ric

Hi Ric,

The file path (and the file itself) are correct.
if I
NSLog(@"Dic %@ ", self.theDictionary);
I get

2012-05-08 02:14:06.271 testObjC[26709:403] Dic Dic
(lldb)

then bang.

Bernard,

I can’t see what’s wrong with what you have – you have my email, why don’t you send me a copy of your testObjC project, and I’ll have a look at it.

Ric

Ok, I got from Ric a working solution. In fact, one should know what are ASOC properties equivalents in ObjC. The docs are unclear on this matter, because scripters just have to declare:

In Objective-C this should be:

No need to deallocate “by hand”.

We had always this problem with the old Memory Manager of the Toolbox, we prevented “handles” (pointers to pointers) to move by freezing them into memory to dereference them safely, and we had to unlock them and free them “manually”. As I read, the Garbage Collector is reliable, and to send messages to nil objects does not make you restart your Mac anymore. --remember the “bomb” icon? :wink:

Happy coding!

Bernard,

See my post above – assign and retain are identical under garbage collection – they both do an assign (you can’t do a retain in GC).

The problem is using an autorelease object without using an local autorelease pool. The error can happen anywhere on the fly because the object is added to a pool in another scope. As soon as the ‘unknown’ pool receives a drain the dictionary is freed. So use alloc->init or new methods just like most of Apple’s example code and use retain->release or turn garbage collector on when you start with Objective-C. It makes the start a bit easier

Well, I don’t want to play on thin ice. What is best?

Compiler LLVM GCC 4.2 with Garbage Collection “supported/required”
or
Compiler LLVM compiler 3.1 with Garbage Collection “unsupported” ?

I hope you’re not trying to share your Objective-C knowledge already with us when you just start. Like Shane mentioned the properties behaves differently with GC on or off. please don’t share bad/incomplete information. Assign, copy and retain are used in different situations. Otherwise Apple wouldn’t give us a choice, you’re not in the ASOC world anymore. Sometimes I want to use assign while the next time I want to use copy or retain. With autorelease I can use a retain without any problem but when no autorelease is used and GC is turned off I know there is a high change of multi retains and will cause leaks. In those cases I use copy, assign or write the get and set myself.

As far for a compiler. In basic terms it only adds some support for changes to a programming language and most of the changes are compiler instructions so I would go for GCC 4.2 (i use it myself). GC is just some machine code that is added to your compiled code. It also runs in 1 - 4 threads next with your code (that’s why you application loses 10% performance in general).

If you are keeping any ASObjC code, in practice you need to use garbage collection. That may change in future; it’s been publicly stated that garbage collection will be deprecated in 10.8.

The whole issue of memory management is a thorny one. Long-time Objective-C programmers are comfortable with retain/release, and many don’t see the need to change. Garbage collection looks doomed (sadly, IMO). ARC (automated reference counting) looks like the way of the future, and arguments about factory methods versus init/new will largely become moot.

For someone starting out like you at the moment, that’s not much comfort…

The supported/required distinction is really for frameworks that will be used in other projects.

I don’t think the compiler will make any difference for you, although the LLVM compiler looks to be the way of the future.

Thanks to remind me that, I almost forgot. :confused: By the way, I didn’t find this myself, I just trying to understand how all this work.

So I’ll use this compiler (it’s not the default one) with garbage collection required. I get one warning:

cc1obj: warning: -Wuninitialized is not supported without -O

which gets away if I change the optimization level (for debug). Is that ok?

No, you’re right, I’m not smart enough to see the differences (and probably I’ll never be), but if I don’t set all options accordingly, the project won’t build. and that makes a difference. :wink:

The project that Bernard sent to me was using ARC, not GC, and the use of assign for the NSMutableDictionary was what was causing his app to crash. Since he mentioned that he was interested in iOS as well as OS X, I think that ARC is the way to go – it certainly seems like the way Apple is pointing us. It is my understanding that ARC takes care of pretty much all the memory management as long as you stick to cocoa ( but core foundation objects are a different matter). If this isn’t true, I hope someone will enlighten me.

As far as retain, assign or copy, it seems like (from what I’ve seen) that as a general rule of thumb, you want to use retain for objects other than strings, where you use copy, and assign for IBOutlets and primitive types. I know this isn’t always true, but for someone starting out in Objective-C, it’s a place to start. I don’t even know whether we should still be using retain and assign, it looks like Apple is moving to strong and weak.

Ric

It takes care of most of the mundane stuff, but you still effectively have responsibility with things like properties.

You’re right.

Properties in projects/files with arc should be defined the same way as other non GC projects. Performance-wise ARC doesn’t drop performance like GC but arc is more statically while GC is more dynamic. GC had a big advantage with objects that are created at run time like ASOC. The big difference is that ARC is a pre compiler while GC works at runtime. The only thing I don’t like about ARC is that it behaves like a zombie (read:stupid). I mean It adds release and retains for you, it could also look if the coder has added a retain or release already but it doesn’t. Another dislike is that I’m not allowed to create C structure anymore with pointers to Objective-C objects. For tool free bridge types (you named core foundation objects) needs a special casting. ARC indeed only applies for objects that have an retain counter (Objective-C objects). In other words for lightweight high level applications arc can be useful but a lot of developers needs to work with core foundation types (which are faster).

However I like the @autorelease{…} because it makes your code better readable, increase performance and best of all you don’t need to have ARC enabled to use this. But I name this because it is introduced with ARC.