Put NSRects into an array, as objects? - objective-c

I want to make a NSMutableArray and fill it up with rectangles created with, say, NSRectMake. But the array only allows objects. What should I do to save the NSRects in an array?

Use NSValue that's especially designed for that stuff. In your case, use valueWithRect:
Everything is explained here in Apple's corresponding Programming Guide.

Related

Storing NSMutableArray

I am currently storing an instance of a class in an NSMutableArray by using NSValue with "valueWithPointer". The problem is within this class I have another NSMutableArray, whenever I convert the instance of the class back from NSValue the NSMutableArray contained within it is of length 0, all of its elements have been removed. Does anyone know why this happens and how to solve it?
Any help would be much appreciated.
Unless there's a very good reason that you specifically need NSValue, you should not add a class instance to an NSMutableArray that way. Just do:
[myMutableArray addObject:myClassInstance];
This does all the right things with regards to memory management (and avoids ugly pointer value stuff), and should let you get at your class instance's array objects after retrieving the object. See the NSMutableArray docs for a quick starter on how to use the class properly.

NSArrayController + NSTableView : automatically save changes without Core Data

OK, so I'm implementing a classic scenario :
A NSPopupButton with some items in it
When the selected value changes, my itemsArray is updated
The itemsArray is linked to an NSArrayController
Each item in the itemsArray is an NSMutableDictionary (with keys : title,content)
An NSTableView displays the titles of the arrangedObjects (binding)
An NSTextView displays the content of the selected item.
Now, what I want is to automatically save any changes to the itemsArray (or itemsArray's item title/content), but without using Core Data (which I suspect might have been the best way to go about it).
I imagine it's quite a basic question this one, but honestly I've never really like Cocoa's auto-magical way of doing things... so, I need your help...
How should I go about that?
You can write an array to a file very easily:
[yourArray writeToURL:someFileURL atomically:YES];
This will work if all the contents of the array are property list objects (i.e. they are NSNumber, NSString, NSDictionary, NSArray or NSData objects). This is the case in your example.
You can then recreate the array using either the arrayWithContentsOfURL: or initWithContentsOfURL: methods when you load from disk.
If your model object is more complex than just an array, then you should make your model object conform to the NSCoding protocol. This means you need to implement the initWithCoder: and encodeWithCoder: methods. You can then use the NSKeyedArchiver and NSKeyedUnarchiver classes to convert your object to and from an NSData representation that you can write to disk.
You should read the Archives and Serialization Programming Guide for more detailed information.
Another solution might be to add a Shared User Defaults Controller and bind the Controller Content Array from the Array Controller to the Shared User Defaults Controller

KVO and NSMutableArray

How can I set KVO (key-value-observing) with an NSMutableArray?
I want to be notified when a change appears in the array. I never used KVO before with a collection like an array.
I think you'll be interested in the answers to this question.
The key is that you can't observe any properties on the array directly—the array is just storage—but you can observe the to-many relationship that's backed by that array (here I'm assuming your array is a property on an object somewhere).
If you don't want to use those special accessors all over the place, your code that owns the array can call
-willChange:valuesAtIndexes:forKey: and
-didChange:valuesAtIndexes:forKey:
as described in this answer.
And if you're on a Mac and not iOS, you should consider NSArrayController.
You can use KVOMutableArray.
It is a subclass of NSMutableArray, and it supports KVO.
disclaimer: I am the author :)

Save list of CGPoints using NSUserDefaults

I have a bunch of CGPoints from a CCTMXLayer I want to save to NSUserDefaults but cannot seem to figure out an elegant way of doing so.
Originally I was hoping to save an NSDictionary with an NSMutableSet for a value containing several NSValues (valueWithCGPoint). From what I can tell neither NSMutableSet or NSValue is supported by NSUserDefaults.
At this point I am considering saving the x&y values of the CGPoint as a string and just converting it back and forth as needed.
There exists a pair of functions NSStringFromCGPoint and CGPointFromString. You can use these to produce an array of strings representing the points for serialization, and then convert back when you're finished.
Box them in NSValue objects. Once they're in there, you can write the NSValues out to disk (since they conform to <NSCoding>) or put them in NSUserDefaults or whatever.

#property(copy) - is an entire copy being made?

I'm getting sublayers of a CALayer with this property accessor:
// #property(copy) NSArray *sublayers
NSArray* layer = mylayer.layer.sublayers;
Since this property uses "copy", every time I simply execute:
mylayer.layer.sublayers
is an entire copy of the sublayers array being made for me? If so that might be bad, because I could have one hundred+ layers, and definitely don't want to create a huge copy of them. I'm just looking to get a count and iterate through the existing layers, just a pointer to the existing layers,
Thank you
When you use the 'copy' declaration and you #synthesize the property, then copy is used when the property is set.
In your example, you are only accessing the value which just gives you a pointer to the sublayers array.
Here's a link to the ADC documentation on this point.
Update
IIRC, the runtime is smart enough to know if the object being set is mutable. If an immutable object is being passed in to the property it is retained and not copied.
In some cases, if you are passing in a mutable object that you want to be able to modify, then you should write your own setter that calls mutableCopy on the object. This is shown in the documentation link that I provided.
I'm not sure I understand your answer Abizern so let me say this:
If you use (copy) on a property you will be making a whole new copy of that object so would be wasting a lot of memory. I'm not sure why they are doing that, they could just use (readonly) instead if they want to protect the values from change. Plus remember most value classes are immutable in Obj-C so they can't change the value anyway.