Translate ASOC into Objective-C?

Ric,
First it wasn’t. I’m just trying to get this thing work and test everything.

Stefan,
The file is a plist file whose first key is array-type and contains 10 strings.

If the file is badly formatted, what will return? A null array (null) or an empty array ()?

PS:
Oh, oh. that’s why not putting “my” produces no result (and no error): the variable is local to the handler, it is not the property anymore.

maybe you should use a standard plist file with a dictionary root element

Ok, it’s working now:

the plist file is a list of dictionaries. No “root” key. Shouldn’t be one?

Thanks!

(Note: I remember now – it took me weeks to understand the basic of ASOC. I had just forgotten :slight_smile: )

Stefan, I’ve seen you post this before, where does this idea come from, that the “normal” plist has a dictionary as its root object? I’ve used plists with arrays at the top with no problem. Apple’s docs say:

" A root property-list object is at the top of this hierarchy, and in almost all cases is a dictionary or an array."

Ric

You’re right, “standard” plist file means that all preference plist files have a dictionary root element as well as the empty plist file from the Xcode file template.
Furthermore all examples in the Property List Programming Guide are dictionary based property lists

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.