What is best approach? NSDictionary Or Custom Object based Data strcuture? - objective-c

I was talking to several developers which approach is best in objective C according to latest trends?
For example: if i am populating data from server in json form, which approach should i use?
I have seen my friends populating data into json objects in past as well as fewer of them in NSdictiory,NSMututable Dictionary, what apple recommends data structure wise?
any help would be appreciated.

I personally greatly prefer custom objects (or Structs for Swift) because it lets me more easily tell what properties the objects have. If you are just passing around dictionaries it makes it much harder (in my opinion) to remember what object you have, what keys it has, and maybe what nested objects it has too. Whereas if you have named classes (again, these ought to be Structs in Swift), then you (and the compiler) can easily know what properties they have. Plus you can easily create instance methods for your objects.
And if you don't want the pain of parsing them yourself there are frameworks that will manage parsing the server response into objects (e.g. RestKit https://github.com/RestKit/RestKit).
If you consider example code from Apple as a "recommendation" from Apple, you can see the way they make a data model in their "Start Developing iOS Apps" here: https://developer.apple.com/library/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson6.html. Yes the example is for Swift but most concepts are comparable.
Apple also has "Cocoa Core Competencies" (https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/ModelObject.html) where they define a modal object as "typically a subclass of NSObject or...a subclass of NSManagedObject."

Related

Project without garbage collector osx

in my school we recieved task to do project in any programming language, but with custom data structure and programming language can not have garbage collector. It was recommended to use C ++. But I have better skills in objective-c. So I disable ARC in my Xcode project and now I should create custom data structure like ArrayList in Java. I cant use NSMutableArray or NSArray. It is possible working with memory like in C++ and create custom data structure?
Thank you for response
You have two basic choices:
Use struct's for your data structures and malloc/free (and friends) for your dynamic memory allocation - just as you might in C(++); or
You can use NSObject derived classes and alloc/init/new/retain/release (and friends) for your dynamic memory management. To do this you must disable ARC.
Given this is a school task you might wish to check the second is acceptable - you are still using the Objective-C reference-counting machinery, even though you are calling the operations manually. Your professor may not deem that acceptable.
The first choice is more basic, you will be completely responsible for all decisions on when memory is no longer required. Indeed you may choose to implement your own reference counting or even mark-sweep.
HTH

How can I do things like Clojure when using immutable collections in Objective-C?

I've become somewhat addicted to using immutable collections (mainly in Clojure, which calls them "persistent data structures"), and would love to be able program this way in some contexts on iOS and OS X.
A key example of where this would be useful is to be able to "change" a dictionary by creating a modified copy, and have change listeners be able to query the difference between the old and new values, rather than try to codify the change as a property change event. Immutable data structures are also a game-changer for concurrent programming: no need for locks.
Yes, you can do this now using the immutable NSArray and NSDictionary instances, but it becomes increasingly inefficient to copy them to make "changed" versions as you have larger and larger collections and/or make changes frequently: a small change to a large data structure then involves a disproportionate amount of work.
I'm looking for a way to enable immutable data programming in Objective-C. To clarify what this might look like, and for some more of the advantages it offers, the research by Phil Bagwell referenced in this SO question is highly relevant.
Please see this article at Ridiculous Fish (written, I believe, by Cory Doras, an engineer on the AppKit team and also creator of the Fish shell):
Array: Our arrays, aren't. http://ridiculousfish.com/blog/posts/array.html
You've answered your question already:
Yes, you can do this now using the immutable NSArray and NSDictionary instances...
The beauty of the Cocoa framework is its simplicity, especially concerning data structures. The idea is that the behind-the-scenes code should determine how to implement the structure, not you. In practice, you only ever need two "types" of data structures: Arrays and Dictionaries (or Maps, if you've come from other languages). Of course, you need many "types" of implementations, but you only really need two ways of accessing your data; if you need more ways, then that's where custom classes and composition come into play.
As for your concern of efficiency: don't worry about it. The article by Cory (Ridiculous Fish) reveals that under-the-hood, Apple has already met your terms for efficiency. It is after all just pointers, as Ian Murray pointed out in the comments: everything is reference counted and only copied if necessary. It is most probable that when you "copy" or "mutableCopy" an NSArray or NSDictionary that the underlying data is not actually copied. To see how this could be implemented, see Rob Pike's article on the Go language here: http://blog.golang.org/slices. I'm almost certain that Cocoa follows a similar pattern, perhaps even to a further extent.
Additionally, with the advent of Objective-C "blocks," it is now more and more feasible to program in a functional style à la LISP variants (such as Clojure). In fact, I would highly recommend this and encourage you to continue on this path. It can lead to much stabler, cleaner code if done right.
I don't think there's a shortcut here.
Just as you imply, Clojure's persistent data structures are quite a different thing from the immutable collections classes that Cocoa provides.
If you want to use Clojure's persistent data structures from Obj-C, the only way to do so is to re-implement them in Objective-C. My understand is that many of these are described in Okasaki's book, Purely Functional Data Structures, and in the papers of Phil Bagwell.
This other answer has some links: What is the data structure behind Clojure's sets?.

Buliding a user profile with NSDictionary or NSMutableArray

I'm trying to create an application that stores profile information..
Name: first Last
Email:
Department:
Title:
What would be the best approach?...
I was thinking of using an NSDictionary for the info.
But I'm unclear on how to combine all the attributes of the profile, into the NSDictionary...
Would I create an NSDictionary for NAMES, then another for EMAILS, ect...?
Any insight is greatly appreciated, Thanks
This is directed at those who suggest a struct: I'm sorry but why even bother using Objective-C if you're not going to use Objective-C? I'm not sure where this "use a struct" trend is coming from but it's absurd when considering primary, first-class app objects that are to be heavily manipulated with the Cocoa API.
To the OP: Use an Objective-C class and be done with it.
An NSDictionary is great as an indistinct container or map and, provided everything in it is compliant, the whole thing (container and contents) can be archived and unarchived with one line of code.
In your case, you already know a predefined set of attributes (and maybe even methods) of this object you want to describe (a Profile), so create an Objective-C class and make it NSCoding compliant so you can stash it in any standard Cocoa container and have it easily archived/unarchived, etc. You can also take advantage of automagic behavior such as having a -fullName property that returns a concatenation of the first and last names while participating rather effortlessly in Key Value Observing, using NSPredicate filters, sorting by key etc. You can also implement -copyWithZone: so a Profile instance is easily copyable, etc.
"Why use a hammer on that nail? It's wasteful. Plenty of perfectly good sticks out there you can put rocks on."
Please ... just use a class. It makes functionality so much simpler to add in the long run.
I know there is a NSUserDefaults object. I haven't worked with it.
There is a tutorial that explains NSUserDefaults

iOS: How to save a custom object that is created in an app

I've been reading up on saving objects, preserving state etc, but I'm still a little confused on the route I should take when saving objects that are created from my app. I have built an app where a user can create a Radio Station with the Genre, name and frequency. Once a user hits save, a "RadioStation" object is created using a custom class and is stored in an NSMutableArray that is placed in the RootViewController. While RadioStation objects can be stored in this array and are displayed correctly in the table view, it's obvious that once the application quits, these are no longer going to be held by the application.
At this point I'm not sure how I should begin to architect this design. Do I need to set up a plist? Should I use Core Data with a SQLite DB? Do I need to research iOS object serialization for both these scenarios? Or is there an more straight forward way that I'm not aware of?
There are three ways to persist data locally:
Store objects in a database using managed objects or SQLite
Store objects in a file in the sandbox using various classes' writeToFile
Store the data in NSUserDefaults
How you persist your object data depends on how you're using it, and what type of data you're saving. CoreData makes sense if you have a lot of objects of the same type and SQL's search and sorting mechanisms would be useful. I tend to use the sandbox for very large files, eg images, sound files, and large agglomerations of data bounced through NSData. And I use UserDefaults for small amounts of data that might be considered "preferences".
You can put anything anywhere you want, and I suggest being familiar with all three mechanisms when you start a new project. Additional techniques, like using NSCoding to serialize and deserialize classes, can be used to make saving data easier. Note that once you've implemented NSCoding, you could store data anywhere and even send it over the wire.
For your RadioStation, I would personally use UserDefaults. The benefit of using NSCoding is that, once you implement initWithCoder and encodeWithCoder, you can stream a hierarchy of objects (eg an array of custom objects, each of which might contain a dictionary, array, or custom object, etc) fairly easily. If the only thing you're saving is an array of strings, then directly using UserDefaults is easy enough.
The most powerful approach is to make your custom object a subclass of NSManagedObject, and store it in an NSManagedObjectContext using Core Data. On iOS this will always use an sqlite database, on Mac OS X you can use sqlite, xml, or a proprietary binary format (smaller/faster than xml).
Depending on how complicated your data structure is, and how likely it is to change in future, this technique may or may not be too complicated for your app. It's a lot of work to setup, and the API is very complicated, but it's the best choice if you need to store tens of thousands/millions of objects in a file.
For your app, I would have a single sqlite file containing all of the radio stations in the app.
The simplest option, is to implement the NSCoding protocol in your custom object's class. Documented here:
http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Archiving/Articles/codingobjects.html#//apple_ref/doc/uid/20000948-BCIHBJDE
The basic theory is your object writes or reads all it's data to a "coder", and then passes the coder on to any child object(s). Outside of the class, you use an "archiver" or an "unarchiver" class to coordinate everything.
Once your custom class implements NSCoding you can read/write it to the disk with:
myObject = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
[NSKeyedArchiver archiveRootObject:myObject toFile:filePath];
This is a very simple approach, but it has a few drawbacks, for example you will need to figure out your own way to support different versions of the file format (perhaps with a different file extension for example).
Many classes in Cocoa/CocoaTouch already implement NSCoding, so they can be written to a file in this fashion (including NSArray, NSString, NSNumber, etc).
For your app, i would use this to store each radio station in a single file. When the app launches, load all the radio stations from a directory. You should consider enabling iTunes drag/drop filesharing for your app, so users can easily share radio station files with their friends or between devices.
This would also fit in well with iCloud for syncing between devices, I haven't looked into iCloud much, but I expect one file per radio station will be the ideal way to implement iCloud syncing.
No need for such things. If you only have like one thing to save, then research this method of NSArray:
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag
I your user can save many radio stations, then you might want to look into CoreData, which has a bit of a curve, but ultimately will be the easiest way.

Too much C-Style in Objective-C programs?

Hi I'm writing this question because I'm a newbie in ObjC and a lot of doubts came to my mind when trying to make my fist training app. The thing is that I have a strong background in C, I've been programming in Java for the last year and I've done some collage stuff with Smalltalk (I mencione this because those are my programming references and those are the languages I'm comparing ObjC with).
The first problem I've encountered is that I don't know where to draw a line between ObjC and C, for example when dealing with math operations, Should I use math.h or there is a more "object-way" like you can do in Smalltalk (aNumber raisedTo: 3) ? How does a person with no background at all in C learns ObjC?.
Another thing that I couldn't find was a collection's protocol (I've looked over the Foundation Framework documentation given by Apple). Because I want to implement an expresion tree class and I wanna know if there are methods that all collections should implement (like in Smalltalk or Java) or I gotta check by hand every collection and see if there is a cool method that my new collection should have.
I don't know if I'm being too stupid or I'm searching for features that the language/framework doesn't have. I want to program in ObjC with the ObjC style not thinking in C, Java or Smalltalk.
Sorry if the question was too long.
Absolutely use <math.h>. You don't way to pay message sending overhead for functions that run in 30 cycles. Even function call overhead seems pretty steep at that point.
More generally, use as much or as little of C-style as you want to. I've seen Objective-C that was nothing but a couple C modules glued together with objective C messages, and I've seen Objective-C that essentially zero lines of code without the square brackets. I've seen beautiful, effective code written both ways. Good code is good code, however you write it.
In general, you'll use C features for numerical calculations. You'll generally use objects for most other things. The reason for this is that objects are way heavier than a simple scalar — there's just no benefit to it. Why would you ever write [[NSNumber numberWithInteger:1] numberByAddingNumber:[NSNumber numberWithInteger:2]] when you can just write 1+2? It's not only painful to read, it's far slower and it doesn't gain you anything.
On the other hand, Cocoa has rich object libraries for strings, arrays, networking and many other areas, and using those is a big win.
Knowing what's there — and thus what the easiest way to do something is — is just a matter of learning. If you think something should be there and you can't find it, you can ask either here or on Apple's Cocoa-Dev mailing list.
As for a collection protocol — there really isn't one. The closest thing to it is the NSFastEnumeration protocol, which defines precisely one method: countByEnumeratingWithState:objects:count:. This lets you use the for (id someObject in someCollection) syntax to enumerate the objects in a collection. Otherwise, all the collections define their own independent interfaces.
The first problem I've encountered is that I don't know where to draw a line between ObjC and C.
My rule is to use C wherever it makes sense to you. Objective-C has the benefit of letting you choose when to be procedural and when to be object-oriented. Go with what fits best with the code you're writing.
Another thing that I couldn't find was a collection's protocol [...] I want to implement an expresion tree class and I wanna know if there are methods that all collections should implement (like in Java) or I gotta check by hand every collection and see if there is a method that my collection should have.
Unlike Java, Objective-C does not have a master protocol for collections like the java.util.Collection interface. Also, there aren't a proliferation of specific container implementations as in Java. However, that gives you the freedom to implement a collection in a way that makes sense for your code.
For building a tree-like structure, you might take a look at NSTreeNode to see if it might be useful to leverage. (It may be more than you're need or want, but might be worth a shot.)
As far as rolling your own collection, I've learned a lot while creating CHDataStructures.framework, and you're welcome to use whatever you like from that code, or just look at my attempts at creating Cocoa-like structures, designed to complement the Foundation collections and operate similarly. Good luck!
Try to use each language for what it's good at. IMHO, this would include Obj-C objects but C-like code implementing methods. So use math.h and concise C code to implement logic, but don't be shy about using Obj-C classes to organize your larger blocks of functionality into something that makes sense.
Also, try to interact with the frameworks using their style so you're not running upstream.
As has been mentioned, there’s no real protocol for abstract collection classes (aside from the NSFastEnumeration protocol which provides the for(id item in collection) syntax when implemented), but there are conventions to follow.
Apple’s Introduction to Coding Guidelines for Cocoa covers some of this, and there is in fact a section on naming collection methods which covers the general cases (though note that generic container classes such as NSArray use the term “Object” as opposed to “Element” listed in the examples there – i.e. addObject:, removeObject:, and so on).
Following the patterns listed here (among others) is actually crucial when you want your classes to be KVC-compliant, which allows other users to observe changes in your object’s properties.