String Problems - objective-c

A very stupid question from a noob.
I have an action, that sets the string of a label.
- (IBAction) changeProductText:(NSString *)str{
lblProductTxt.text = str;
}
This is the string I want to set that to:
TestText = [NSString stringWithFormat:#"Hi"];
And this is how I am doing it:
[self.navigationController pushViewController:nextController animated:YES];
[nextController changeProductText:TestText];
My problem is that it wont set the string to anything is random whats going into the string. It may crash when I click on the cell it may not, so I am doing something wrong.

stringWithFormat gives you an autoreleased format, without seeing more of the code I'm guessing its hitting an autorelease pool and you're trying to access garbage that was your string.

Is this the exact sequence of the statements?
[self.navigationController pushViewController:nextController animated:YES];
[nextController changeProductText:TestText];
I am not 100% sure but I believe that the second line will not be executed before the nextController is being pushed.
Try to reverse them.
(1st create and initialize the nextController)
2nd assign all values that you want to pass down to nextController
3rd push nextViewController on the stack of View Controllers.
[nextController changeProductText:TestText];
[self.navigationController pushViewController:nextController animated:YES];

The only parameter of an IBAction is the sender:
- (IBAction) clickMyButton: (id) sender;
A string is hardly a valid sender for an action, so whatever you are setting to lblProductTxt.text, it is not a string, it is the sender that performs the action.
In your action method, you can of course set lblProductTxt.text. You'll have to find out yourself where you get the string.
Update
From your comments I deduce you don't have an IBAction, you simply have a void method. Your use of IBAction got me on the wrong foot. Declare it like:
- (void) changeProductText: (NSString *) newText;
Omit the (IBAction) designator, as that is only necessary for, well, real IB action methods.
No matter if you use
NSString *testText = [NSString stringWithFormat: #"Hi"];
or
NSString *testText = [NSString stringWithString: #"Hi"];
The result is exactly the same: an autoreleased NSString with the text "Hi". Only the way it was created is slightly different. If one works and the other crashes, then the same thing is wrong and you are just lucky it doesn't crash.
Now what is wrong is impossible to see from what you posted so far.

Related

Set label title from mouseEntered in objective-c

I have this code in my NSButton subclass:
-(void)mouseEntered:(NSEvent *)theEvent{
NSLog(#"ENTER");
NSString *myString = #"foo";
[myTextField setStringValue:myString];
}
-(IBAction)changeStringValue:(id)sender{
NSString *myString = #"foo";
[myTextField setStringValue:myString];
}
The IBAction works fine but the same method of myTextField called inside the mouseEntered event doesn't work. The event is working (except setString), in fact I can see the NSLog and if I insert NSLog(#"%#", myTextField.stringValue);, it says null.
Does anyone have a clue?
Edit: I noticed that the previous stringValue NSLog, if inserted in -(void)awakeFromNib{...}, occours 2 times even if there's only one button of MyButton class: one time it's correct and the other time it's null. I'm a little bit confused.
Edit2: i've inserted [self performSelectorOnMainThread:#selector(changeStringValue:) withObject:myTextField waitUntilDone:YES]; inside the mouseEnter: event and NSLog(#"Running"); inside the changeStringValue function: now hovering the button i call the function (i see the "running" log) but nothing happens. The function, as a Sent Action assigned to a button, is still working. I've also tried with waitUntilDone:YES/NO and withObject:myTextField/self but it's the same.

Passing a reference and copying the object from another controller. Objects keep disappearing

I know this is a relativly easy question, but I just can't figure out how to solve this problem:
One of my views will receive a dragOperation and the performDragOperation method should pass the NSURL to my AppDelegate which puts it in an mutArray...
The problem is, that I pass over a reference and the object disappears the moment performDragOperation is done. So I tried several things:
in performDragOperation:
//Puts the reference itself in the folderPaths Array
AppDelegate *appDelegate = [NSApp delegate];
[[appDelegate folderPaths] addObject:referenceTotheNSURLObject];
/* tried creating a NSString and putting it in too. Same result because local variables will disappear */
So I created a method in AppDelegate and tried different things:
- (void)addFilePath:(NSURL *)filePath {
NSURL *copyOfURL = [filePath copy];
[[self folderPaths] addObject:copyOfURL];
}
This makes the most sense to me and the only reason I can think about why this doesn't work is, because copyOfURL itself is a pointer and it points to an localObject that will disappear the moment the addFilePath method is finished? But I'm not allowed to use
NSURL copyOfURL = [filePath copy];
I also tried recreating an NSString object again. Same results.
- (void)addFilePath:(NSURL *)filePath {
NSString *pathString = [filePath absoluteString];
[[self folderPaths] addObject:pathString];
}
I know it will be some relatively simply solution but I'm stuck and can't figure it out. Thanks for your time!

Can't add to an NSMutableArray with addObject method

I am having an issue with the addObject method of an NSMutableArrayObject. Here's the code I'm using right now:
- (void)addBirdSightingWithName:(NSString *)name location:(NSString *)location {
BirdSighting *bird;
NSDate *today = [NSDate date];
bird = [[BirdSighting alloc] initWithName:name location:location date:today];
[self.masterBirdSightingList addObject:bird];
NSLog(#"Elements: %d", [self.masterBirdSightingList count]);
}
When this code runs, the NSLog call prints the value 0 to the console. I don't know what could be causing this.
EDIT:
I have looked deeper into the code, and I have discovered that the problem is that my BirdSightingDataController is never initialized. Now my question is: Where can I place the init for my BirdSightingDataController? In the viewDidLoad?
Thanks to everyone for the help.
Did you allocate memory to masterBirdSightingList?
self.masterBirdSightingList = [[NSMutableArray alloc] init];
In almost every case where cellForRowAtIndexPath: is not called is because numberOfRowsInSection: returns 0.
Place a log there and make sure you return more than one item and you should be able to see your cells. If you need further help please post the code in your:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
Check your property accessor. Are you sure it's returning the correct object? Make sure the name of the property matches the instance variable or you've specified it correctly (For example: #synthesize masterBirdSightingList = _masterBirdSightingList;. If the property accessor doesn't match the iVar, it will return nil. Of course, if you're manually implementing the accessor check your code there. If you're not, you could also try manually implementing it to make sure.
To do a quick check, remove the self.masterBirdSightingList and replace it with masterBirdSightingList (assuming that's the iVar name) to access the iVar directly and see what happens.

Warning about making pointer from integer without a cast -- explanation needed

I have this code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic
NSLog(#"didSelectRowAtIndexPath");
//The hud will dispable all input on the view
HUD = [[MBProgressHUD alloc] initWithView:self.view];
// Add HUD to screen
[self.view addSubview:HUD];
// Regisete for HUD callbacks so we can remove it from the window at the right time
HUD.delegate = self;
HUD.labelText = #"Loading Events, Please Wait..";
int i = indexPath.row;
//Show the HUD while the provided method executes in a new thread
[HUD showWhileExecuting:#selector(loadData:) onTarget:self withObject:i animated:YES];
}
And I get this warning:
warning: passing argument 3 of 'showWhileExecuting:onTarget:withObject:animated:' makes pointer from integer without a cast
Can somebody please explain what I'm doing wrong here? Could someone also briefly explain the situation with ints in Objective-C, coming from Java I find it odd that they are so confusing to use.
The problem is that showWhileExecuting:onTarget:withObject:animated: takes an object as its third argument. To get aroung this, you can wrap integers as objects using the NSNumber class
[NSNumber numberWithInt:i]
You will then have to unwrap the argument in the loadData: method by calling
[argument intValue]
The method takes an object as a third argument (withObject), but you passed an int instead.
Apparently, you provided an integer(int i) instead of an object pointer(type of id). It is not safe. Use NSNumber instead.
int i;
...
NSNumber * numberI = [NSNumber numberWithInt:i];
[HUD showWhileExecuting:#selector(loadData:) onTarget:self withObject:i animated:YES];
All of the answers above are the "correct" ones. I.e. be a good boy and use and NSNumber to pass the value.
However, … the following will work
"damn you, compiler, i'm smarter than you are:"
(cast your integer, totally not a valid object, to id)
[HUD showWhileExecuting:#selector(loadData:)
onTarget:self
withObject:(id)i
animated:YES];
i'm guessing (you didn't say), that your load data method looked like this:
- (void)loadData:(int)i { …
you will see code like this, which is the only reason i mentioned it.
you should be familiar with it.
someone thinks that saving 1 object allocation is going to make their code efficient; don't sweat object allocations, and wrap it up in an NSNumber as shown above
most C compilers will handle this correctly, but it's not guaranteed

Objective C unable to update UILabel more than once

I have a method which I created that appends some new text to a UILabel. I've tried two ways of doing this (one is commented out) but both of them only update the label the first time. Any more calls to this method do not update the label.
- (void) updateLog: (NSString*) text
{
/*
NSMutableString *newText = [logLabel.text mutableCopy];
[newText appendString: text];
logLabel.text = newText;
*/
logLabel.text = [logLabel.text stringByAppendingFormat:#"%#", text];
}
I am calling the method like this (the method is in the viewController):
[viewController updateLog: #"\nStarting...\n"]; // Works
[viewController updateLog: #"Test\n"]; // Does not work
I have searched everywhere for an answer, what am I missing? Thanks!
UILabel, unless set up otherwise, only displays a single line of text.
Change the numberOfLines property if you want more.
I actually figured this out. Turns out the string WAS being successfully updated, but the label size was too small, so the text was hidden.