Can't read this code from Apple template - objective-c

I do not understand the Objective-C in the following method taken from Apple's Master Detail Template:
- (void)insertNewObject:(id)sender
{
if (!_objects)
{
_objects = [[NSMutableArray alloc] init];
}
[_objects insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0
inSection:0];
[self.tableView insertRowsAtIndexPaths: #[indexPath]
withRowAnimation: UITableViewRowAnimationAutomatic];
}
The code is in the MasterViewController.m file. The points of confusion for me are:
- what does #[indexPath] mean? Is this a syntax for making something an array. I have only run into the '#' as the character denoting a string. Clarification: I understand what an NSIndexPath is and how it functions. I am not familiar with the syntax for putting an object in brackets preceded by the # character. Does this make something an array? What if I had several NSIndexPaths? Can I load all of them into an array in this manner #[indexPath1, indexPath2, indexPath3] Does this work with anything derived from NSObject? Is the result always an array? Where is this documented in the language - what is this language feature called (so I can look it up)?
The method insertRowsAtIndexPaths:withRowAnimation seems to specify the locations to put something into the table but not exactly what to put. How does the method know what object to use as the data source when inserting items into the table. The delegate and data source relationships are specified in the xib so it is apparent that the MasterViewController will handle the association of data with the table, but there does not seem to be any relationship with the NSMutable *_objects; array and the table specified anywhere.
Thanks for the help in explaining this as it is apparent I am missing some pretty basic stuff.

Is this a syntax for making something an array
Yes. In modern Objective-C, as understood by the latest clang compiler, there are some more # directives for easily creating hard-coded objects:
#[object1, object2]
creates an NSArray;
#{#"key1": value1, #"key2": value2}
creates an NSDictionary,
#"hello world"
creates an NSString, as usually, and
#1, #2, #YES, #3.1415927
create NSNumber instances, respectively.
How does the method know what object to use as the data source when inserting items into the table.
It uses the data source currently set on the table view it is called on.

Related

How to add sqlite database values into an array?I was retrived but how can I put these values into array?

1) How to add sqlite database values into an array.
2) I was retrived my sqlite database values but how can I put these values into an array for to show the another viewcontroller tableview.
3) What can I write in viewcontroller.h and viewcontroller.m .
4) Below one I wrote but it getting error "No known class method for selector'getData'"
Code:
- (void)viewDidLoad
{
[super viewDidLoad];
depositArray=[[NSMutableArray alloc]init];
depositData=[[NSMutableArray alloc]init];
depositArray=[dbModelClass getData:str];
for( NSDictionary *dis in depositArray)
{
[depositData addObject:[dis objectForKey:#"depositTable"]];
}
Did you #import the header that declares the incorrectly named getData: method?
Note: If you are writing raw SQL, you are wasting your time. Use FMDB (or similar) if you need database portability beyond iOS/OS X. If you are targeting only iOS / OS X, then Core Data is an excellent solution that has a very tight integration with the system.
Some other issues:
This makes no sense:
depositArray=[[NSMutableArray alloc]init];
depositArray=[dbModelClass getData:str];
The first line allocates an array. The second line immediately assigns a new value to the variable pointing to that original array, both losing the reference to it and leaking memory.
Also, methods should not be prefixed with get. That is reserved for very specific use cases.

Populating TableView line by line in Obj-C

I'm looking for a way to populate a table view from one single document, namely I want to load a .po file.
I would like each line of my table view to load one line of text from the PO file.
Ideally, I would like to have one line in the first column, and the corresponding translation in the second column (to get a clear view of the contents).
I have not worked much with table views yet so please forgive my ignorance!
I have done my research but I find the apple documentation confusing and very unclear -- and didn't find much online...
Thanks in advance for any help!
bbum is correct, you don't push data to your table, you provide it and the table displays it. Friday I did a quick mock-up on putting a text file displayed line by line, so maybe some of the code can help some.
Get a table view connected with an outlet to it's data source, then you can do something like this:
// Class variable in your table delegate object
NSArray* lineList;
IBOutlet NSTableView* table;
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
return [lineList count];
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
return [lineList objectAtIndex:row];
}
// Be sure to use the proper encoding for your text file
// do something like this to load your text file.
- (void) loadData:(NSString*)ourPath
{
NSError* err = nil;
NSString* fullFileText = [NSString stringWithContentsOfFile:ourPath encoding:NSMacOSRomanStringEncoding error:&err];
if (err)
NSLog(#"Err: %#, %d", [err localizedDescription], [err code]);
if (fullFileText)
{
lineList = [[fullFileText componentsSeparatedByString:#"\n"] retain];
[table reloadData];
}
}
In your case you may want to hold an array of dictionaries, using a different key for both versions of your text. That way you can have two columns. The NSTableColumn will tell you which column you will be drawing into when tableView:objectValueForTableColumn: gets called. The other option you have here is making a custom cell that has two fields in it but that's probably overkill for what you're asking.
Note also that there are a number of other optional delegate calls you can add for more flexibility of how you show your data.
Additionally for more dynamic complex tasks I've found that bindings are better. They can be confusing if you're not comfortable with them though. For simple tables it's often just as easy to go this route. Good luck!
You don't push data to a table view, it pulls data from you. This can be done with either bindings or by implementing the table view data sour (which are a little bit different, but mostly the same, between the NS* and UI* platforms).
The NSTableView and UITableView documentation both have links to examples and programming guides. Read those and if you still don't get it, ask a specific question.

saving an array

how is it possible to save an array in multiple locations ie. different view controllers in order to save the data in the arrays and allow it to be used afterwards by a table?
edit
objective c i have an ibaction with code
[[NSMutableArray alloc] init];
[favoritesArray addObject: #"one"];
//and in the fav table view this code//
favoritesArray = [[NSMutableArray alloc]init];
didContain = [[NSMutableArray alloc]init];
if ([favoritesArray contains:#"one"]);
{ [didContain addObject:#"trial"]; }
however its crashing at the if part...
[[NSMutableArray alloc] init];
[favoritesArray addObject: #"one"];
I assume you actually have the “favoritesArray =” in the original code, and simply missed it when copying. Otherwise, you're dropping the array on the floor and favoritesArray still holds nil.
if ([favoritesArray contains:#"one"]);
{ [didContain addObject:#"trial"]; }
however its crashing at the if part...
There are two problems with your if statement:
NSArray does not respond to contains:, which is what the crash is telling you. You need to send your array a message it does respond to, such as containsObject:, which is listed in the documentation.
As I indicated through the formatting I applied to your code, the if statement does not relate to the { [didContain addObject:#"trial"]; } statement that follows it.
That's because you put a semicolon after the if condition. An if statement does not take a semicolon between the condition and the statement; the statement must directly follow the condition (i.e. be immediately after the )). Moreover, a semicolon by itself is a valid, empty statement.
So, you have an empty statement subject to the if (if the favorites array contains #"one", do nothing), and you have the statement you meant to have controlled by the if standing on its own, unconditional.
Cut out the semicolon after the if so that the { … } binds to the if instead of being a separate statement.
Alx, are you trying to access the data in favouritesArray from multiple objects? This is what I think you are trying to do, but without more context it is difficult to suggest a solution. Here is one possible approach:
Declare favouritesArray as a property in your controller class. (You could use #property and #synthesize to achieve this.)
Then, in your views, add your controller as an IBOutlet (called, say, myController). Then make connections in Interface Builder between your view and the controller. You will then be able to access the array from your view classes by writing:
[[myController favouritesArray] objectAtIndex:3], for example.
In general, it is a bad idea to 'copy' data between different objects in your program. Unless there's a very good reason to do this, use references instead. Try to think about what object is the 'owner' for that array, and put it in that class.

Populating NSTableview from a mutable array

I've been attempting this for two days, and constantly running into dead ends.
I've been through Aaron Hillegass's Cocoa Programming for MAC OS X, and done all the relevant exercises dealing with NSTableview and mutable arrays, and I have been attempting to modify them to suit my needs.
However none of them seem to be using an array with objects as a data source, it seems to use the tableview as the datasource.
I'm trying to implement Jonas Jongejan's "reworking" of my code here, with a Cocoa front end to display the results.
Any pointers or suggestions I know this should be simple, but I'm lost in the wilderness here.
I can populate the table by setting the array
It's pretty simple really, once you get to understand it (of course!). You can't use an NSArray directly as a table source. You need to either create a custom object that implements NSTableViewDataSource or implement that protocol in some existing class - usually a controller. If you use Xcode to create a standard document based application, the document controller class - (it will be called MyDocument) is a good class to use.
You need to implement at least these two methods:
– numberOfRowsInTableView:
– tableView:objectValueForTableColumn:row:
If you have a mutable array whose values you'd like to use in a table view with one column, something like the following should do as a start:
– numberOfRowsInTableView: (NSTableView*) aTableView
{
return [myMutableArray count];
}
– tableView: (NSTableView*) aTableView objectValueForTableColumn: (NSTableColumn *)aTableColum row: (NSInteger)rowIndex
{
return [myMutableArray objectAtIndex: rowIndex];
}
It has just occurred to me that you could add the above two methods as a category to NSArray replacing myMutableArray with self and then you can use an array as a data source.
Anyway, with a mutable array, it is important that any time you change it, you need to let the table view know it has been changed, so you need to send the table view -reloadData.
If your table view has more than one column and you want to populate it with properties of objects in your array, there's a trick you can do to make it easier for yourself. Let's say the objects in your array are instances of a class called Person with two methods defined:
-(NSString*) givenName;
-(NSString*) familyName;
and you want your table view to have a column for each of those, you can set the identifier property of each column to the name of the property in Person that that column displays and use something like the following:
– tableView: (NSTableView*) aTableView objectValueForTableColumn: (NSTableColumn *)aTableColum row: (NSInteger)rowIndex
{
Person* item = [myMutableArray objectAtIndex: rowIndex];
return [item valueForKey: [tableColumn identifier]];
}
If you replace valueForKey: with valueForKeyPath: and your Person class also has the following methods:
-(Person*) mother;
-(Person*) father;
-(NSString*) fullName; // concatenation of given name and family name
you can add table columns with identifiers like: father.fullName or mother.familyName and the values will be automatically populated.
You could go the datasource route and do all of the heavy lifting yourself, or you could let bindings do all the heavy lifting for you. Add an NSArrayController to the nib file that has the table view in it. Make sure that the File's Owner of the nib is set to the same class that has the mutable array in it. Bind the contentArray of the array controller to File's Owner.myMutableArray. For each column bind Value to the array controller arrangedObjects and add the appropriate key path. This will allow you to get things like user sorting for free if you ever need it.
On the iPhone (I know you're talking about Mac, but maybe this could help) you have to use delegation for loading a tableView. It asks for a cell and you use your array to fill-in the data where needed.
I'm not sure if this works for the Mac, but it'd be worth looking into.
Maybe set dataSource to self and use those delegate methods to access your array based on the row and column #
Apple has a whole guide for Table View Programming so I suggest you start with the Using a Table Data Source section of the that guide.

Setting text for NSTextView with an NSString variable, considering reference counting

I have the following code in a function in my .m file:
desc = [my executeFunction]; // desc is returned by executeFunction
data = [desc objectAtIndex:0]; // data is declared in the .h file
data2 = [desc objectAtIndex:1];
[myTextField setString:data]; // myTextField is connected to an NSTextView in IB
[myTextField setString:data2];
How am I supposed to be writing the 4th and 5th lines? How / where do I release data and data2?
You don't. You haven't received data or data2 from a method with a selector containing alloc, new or copy or a function with a name containing Create, so you are not responsible for releasing them.
Have a look at http://boredzo.org/cocoa-and-cocoa-touch-intro/.
Revise the Cocoa Memory Management Guidelines and determine whether releasing is necessary in this case. There are very specific, yet very simple rules regarding a retain and release pattern. Commit these rules to memory (pun intended).