Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Mvkoe

macrumors regular
Original poster
Aug 4, 2008
103
3
Belgium
Hey

As I'm getting a bit better and understanding some things more and more. I'm in this situation where I want to add new strings to my tableview.

So I've setted up everything, and made an addViewController with a textfield etc. When someone presses the button this will be the Action:
Code:
-(IBAction)doneKnop:(id)sender{
    NSString *myString = vraagVeld.text;
    [arrayData addObject:myString];
    [arrayData writeToFile:@"opties.plist" atomically:NO];
    [[self navigationController] popViewControllerAnimated:YES];
}

and at the beginning, i init my array plist:
Code:
- (void)viewDidLoad
{
    [super viewDidLoad];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"opties" ofType:@"plist"];
    NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:path];
    self.arrayData = data;
}

But it seems to not write the file ? What am i doing wrong ?

Grz
 
Last edited:

Mvkoe

macrumors regular
Original poster
Aug 4, 2008
103
3
Belgium
Where do you think you are saving the file to?

BTW, here are the documents from the apple site. Look up writeToFile and see what the requirements are for that method. The answer it there.

https://developer.apple.com/library...Class/NSArray.html#//apple_ref/occ/cl/NSArray

I've looked it up so i've changed my path a bit:
Code:
-(IBAction)doneKnop:(id)sender{
    
    NSString *myString = vraagVeld.text;
    
    [arrayData addObject:myString];
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"opties" ofType:@"plist"];
    
    [arrayData writeToFile:path atomically:YES];
    
    NSLog(@"%@", arrayData);

    [[self navigationController] popViewControllerAnimated:YES];
}

and when I check my array it's in there by this:
Code:
(
    "Wie betaald?",
    "Wie is bob?",
    "Wie is Wat?",
    "Wie ben ik?",
    blah
)

But it seems not to write it .. Am i still doing something wrong?
 

TheWatchfulOne

macrumors 6502a
Jun 19, 2009
838
972
What exactly is happening (or not happening) that makes you feel your file is not being written?

The more details you give about what you've tried, the better the help you will receive.
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
Your application bundle is read-only. On the device you can't write a file there. You should decide on a location for your plist file that is in your Application Support folder. When your app launches check if the file exists in the Application support folder. If it isn't there then copy the version from your bundle to the Application Support folder. After that always read/write the file from the Application Support folder.

BTW, writeToFile: returns a value telling you if it worked. You should inspect that value.
 

Mvkoe

macrumors regular
Original poster
Aug 4, 2008
103
3
Belgium
Your application bundle is read-only. On the device you can't write a file there. You should decide on a location for your plist file that is in your Application Support folder. When your app launches check if the file exists in the Application support folder. If it isn't there then copy the version from your bundle to the Application Support folder. After that always read/write the file from the Application Support folder.

BTW, writeToFile: returns a value telling you if it worked. You should inspect that value.

Okay so I'm doing it wrong. I'm trying to write to my main bundle. What i'm trying to do is, adding a new row to my table view.

So what I need to do is.

  1. Always check if the plist is in the Application support folder of my app, if it isn't there copy it over there.
  2. Only work with the Application support plist, where i can read write from it?

Am I right?

EDIT:
Okay, so it's working now, i can read and write to it. But now the problem is, that my TableView doesn't update.

When i press the done button:
Code:
[[self navigationController] popViewControllerAnimated:YES];

Will execute, but this seems to not update my TableView, it only updates when i close the app and reopen it.
 
Last edited:

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
The usual way to update a table view with new data is to 1, update your data model, 2, [self.tableView reloadData].
 

Mvkoe

macrumors regular
Original poster
Aug 4, 2008
103
3
Belgium
The usual way to update a table view with new data is to 1, update your data model, 2, [self.tableView reloadData].

Thanks for the help, I already figured it out by searching a bit, and remaking the adding, because the self.tableview can't be used in my adding vc.
 

Mvkoe

macrumors regular
Original poster
Aug 4, 2008
103
3
Belgium
All the more reason to be using a model layer. A viewController updates the model data and then another viewController retrieves that model data.

Mmm oke, that should do it then. Got any book or tutorial where this is covered ?
 

Mvkoe

macrumors regular
Original poster
Aug 4, 2008
103
3
Belgium
Have you finished reading "Beginning iOS 5 Programming" yet? That's the David Mark / Jack Nutting / Jeff LaMarche one you have, yes?

P.S. Be sure to check out this Apple doc as well: Concepts in Objective-C Programming

I'm almost done with it, read the basics till chapter 10: Storyboarding. The model layer that you're saying, in what chapter like would it been discussed ? would it be in "Basic Data Persistence" ?
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
Slow down, don't get ahead of yourself, step away from the real coding and finish reading the book. Make sure you're comfortable with everything it's covered. If not, read it again. Take working apps and tweak things. Read through that Apple doc I linked to. Figure out what areas you need to dig deeper in to understand. Take it easy.
 

Mvkoe

macrumors regular
Original poster
Aug 4, 2008
103
3
Belgium
Slow down, don't get ahead of yourself, step away from the real coding and finish reading the book. Make sure you're comfortable with everything it's covered. If not, read it again. Take working apps and tweak things. Read through that Apple doc I linked to. Figure out what areas you need to dig deeper in to understand. Take it easy.

Hehe oke, It's just that I'm happy that most of the stuff work that I try, and want to build upon that as fast as I can sometimes. The only problem is that I'm dutch, and sometimes think like, hmm i need to find a "easy" explenation about something or a "this is it, and this is how it works" straight to the point.

So the Model Layer, is an NSobject class, that i need to alloc and init in each class i want to use. Then with getters and setter using the class ?

Like this?:
http://developer.apple.com/library/...s.html#//apple_ref/doc/uid/TP40011318-CH9-SW1

EDIT:

Okay so it's going quite well! I'm almost getting there, so i have made a model layer with all my data things in. I can get it in my tableview etc, but now i got one problem. When adding something new to my tableview it gives an error that i don't understand:

Code:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'

But I'm doing a NSString with addObject to my NSMutableArray like this:

Code:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
    if(buttonIndex == 1){
        NSString *naarArray = [actionSheet textFieldAtIndex:0].text;
        [self.dataController.vraagArray addObject:naarArray];
        [self.dataController saveData];
        [self.tableView reloadData];
    }
}
 
Last edited:

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
That error says that somewhere in your code there is a call to insertObject:AtIndex: on an NSArray. That method can only be called on an NSMutableArray.

Look up the words mutable and immutable and understand how they apply to all the container classes in Foundation Kit.

You need to verify the place in your code that this error is occurring. One way to do that is to set a breakpoint on All Exceptions and then run the app in the debugger until you get the error. At that point the app will be stopped in the debugger and you should see the stack trace in the debugger stack trace view. Another way is to run the app outside the debugger on the device and get a crash log.
 

Mvkoe

macrumors regular
Original poster
Aug 4, 2008
103
3
Belgium
That error says that somewhere in your code there is a call to insertObject:AtIndex: on an NSArray. That method can only be called on an NSMutableArray.

Look up the words mutable and immutable and understand how they apply to all the container classes in Foundation Kit.

You need to verify the place in your code that this error is occurring. One way to do that is to set a breakpoint on All Exceptions and then run the app in the debugger until you get the error. At that point the app will be stopped in the debugger and you should see the stack trace in the debugger stack trace view. Another way is to run the app outside the debugger on the device and get a crash log.

You I tought that too, but the problem is that i don't use an NSArray, the only NSArray that i use if for my path loading, and that is done without error.

I'll try setting a breakpoint, to bad i don't have expierence with breakpoints..

EDIT:

Okay so i've setted a breakpoint, did it step by step, seems all fine by me, putting an NSString in my @property (nonatomic, copy) NSMutableArray *data;

And then suddenly it jumps to this code:
Code:
#import <UIKit/UIKit.h>

#import "AppDelegate.h"

int main(int argc, char *argv[])
{
    @autoreleasepool {
    ->>>>>>    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

EDIT:

Hmm okay, by changing my @property (nonatomic, copy) to @property (nonatomic, strong) it works.. But it was told to me that you should always use copy as best option for Strings,arrays etc.. How come i need to use Strong in this case ? Can someone explain ?
 
Last edited:

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
Hoist by his own petard.

What do you think this does?

Code:
_myMutableArray = [[[NSMutableArray alloc] init] copy];

What is the class of _myMutableArray?

When you're stopped at a breakpoint move the slider at the bottom of the pane all the way to the right so you can see the full stack trace.
 

larswik

macrumors 68000
Sep 8, 2006
1,552
11
Mvkoe - If you are on Chapter 10 of that book you should have a good idea of what mutable and immutable are like NSArray and NSMutableArray. I would slow down and even start over in the book and really get it. dejo mentioned that you should understand what you are reading before you move on, and it is a good idea.

When I was learning I did the same thing you are doing now and reading your posts sounds familiar. If you treat programming like a race you will lose. It sounds like you are reading every chapter and before you understand the material you are moving on and skipping over what you don't understand.

Your probably copying and pasting lots of code from the internet to Frankenstein your program together. If you are truly coming from a Java background then the cross over should not be that hard. Java deals with mutable and immutable object too.

I would go back to square one and really understand every chapter by writing lots of small programs that cover the material in that chapter. That is what was recommended to me when I started but I thought that knew better and soon I was asking for help like you are now because I did not get it.

My 2 cents if you want to be a good programmer, which I hope to be some day too.
 

Mvkoe

macrumors regular
Original poster
Aug 4, 2008
103
3
Belgium
Mvkoe - If you are on Chapter 10 of that book you should have a good idea of what mutable and immutable are like NSArray and NSMutableArray. I would slow down and even start over in the book and really get it. dejo mentioned that you should understand what you are reading before you move on, and it is a good idea.

When I was learning I did the same thing you are doing now and reading your posts sounds familiar. If you treat programming like a race you will lose. It sounds like you are reading every chapter and before you understand the material you are moving on and skipping over what you don't understand.

Your probably copying and pasting lots of code from the internet to Frankenstein your program together. If you are truly coming from a Java background then the cross over should not be that hard. Java deals with mutable and immutable object too.

I would go back to square one and really understand every chapter by writing lots of small programs that cover the material in that chapter. That is what was recommended to me when I started but I thought that knew better and soon I was asking for help like you are now because I did not get it.

My 2 cents if you want to be a good programmer, which I hope to be some day too.

Thanks for the comment, but the code that i'm writing is with help of the book, and with trying to understand how things work, i don't really copy code from the internet without understanding what it really does.

The only problem is that I need to get deeper in immutable and mutable things, and trying to understand the thing of "copy".

In my code i'm always trying to improve things so that it's clean.

Hoist by his own petard.

What do you think this does?

Code:
_myMutableArray = [[[NSMutableArray alloc] init] copy];

What is the class of _myMutableArray?

When you're stopped at a breakpoint move the slider at the bottom of the pane all the way to the right so you can see the full stack trace.

It allocates an piece of memory for the NSMutableArray, that's a class of NSArray, then Initialize it. And then the copy i don't know?
 

ChOas

macrumors regular
Nov 24, 2006
139
0
The Netherlands
It allocates an piece of memory for the NSMutableArray, that's a class of NSArray, then Initialize it. And then the copy i don't know?

(I'll just go Dutch here so it might make more sense to Mvkoe)

Wat je doet is: Je roept een nieuw object tot leven van type NSMutableArray. Daarna stuur je init naar dat object. Niets aan de hand.

Maar wat je aan _myMutableArray geeft is een KOPIE van dat object. Dus opeens bestaan er 2! Een waar _myMutableArray naar wijst en 1 waar eeeh... niets meer naar wijst. Dat is een memory leak.

Als je 'strong' gebruikt is dat ongeveer gelijk aan het oude 'retain' in Obj-C. Je neemt eigenlijk het eigenaar zijn op je. Wat er dan gebeurt is: Maak een NSMutableArray initialiseer, en RETAIN. Dat betekent dat de ontvangende parameter (_myMutableArray) voor een gedeelte eigenaar wordt van dat object. Er is geen kopie meer, er is alleen bekend dat er MINSTENS 1 echte eigenaar van is. Zodra je die 'copy' doet is er alleen een eigenaar van het gekopieerde object. Aangezien er geen eigenaar was van het origineel blijft deze 'rondzweven' in het geheugen.
 

Mvkoe

macrumors regular
Original poster
Aug 4, 2008
103
3
Belgium
(I'll just go Dutch here so it might make more sense to Mvkoe)

Wat je doet is: Je roept een nieuw object tot leven van type NSMutableArray. Daarna stuur je init naar dat object. Niets aan de hand.

Maar wat je aan _myMutableArray geeft is een KOPIE van dat object. Dus opeens bestaan er 2! Een waar _myMutableArray naar wijst en 1 waar eeeh... niets meer naar wijst. Dat is een memory leak.

Als je 'strong' gebruikt is dat ongeveer gelijk aan het oude 'retain' in Obj-C. Je neemt eigenlijk het eigenaar zijn op je. Wat er dan gebeurt is: Maak een NSMutableArray initialiseer, en RETAIN. Dat betekent dat de ontvangende parameter (_myMutableArray) voor een gedeelte eigenaar wordt van dat object. Er is geen kopie meer, er is alleen bekend dat er MINSTENS 1 echte eigenaar van is. Zodra je die 'copy' doet is er alleen een eigenaar van het gekopieerde object. Aangezien er geen eigenaar was van het origineel blijft deze 'rondzweven' in het geheugen.

Bedankt! Dat is mooi uitgelegd, hier ben ik opeens veel meer mij dat ze in een boek zouden uitleggen met allemaal moeilijke termen in het Engels!
--
I'll just start reading some basic Objective-C books, for getting really then hang of these things!
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
Never had anyone go Dutch on me before.

This issue is a somewhat subtle issue that I wouldn't expect a beginner to figure out. The rules for when to make a @property copy or strong are a little complicated. The simple rule is "Never mark a @property as "copy" for a mutable type."

If you change your @property for the NSMutableArray to be "strong" and not "copy" things should work the way you expect.

The copy method returns an immutable object. mutableCopy returns a mutable object but there is no "mutable copy" adornment for @properties.

Using "copy" protects your code against setting a mutable object when you want an immutable object. But there is no need to have this kind of protection when your object type is mutable.
 

Mvkoe

macrumors regular
Original poster
Aug 4, 2008
103
3
Belgium
Thanks for all the help people! I'm getting there, made a singleton. I can code the things I want without copy pasting code from the internet!

I'm pretty happy for now! :D
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.