Trouble while adding column - Cocoa - objective-c

just a simple problem (I hope !)
I've got a void method which add a column to a table.
Why if I call that method programmatically (ex: [self method] ) my table won't update and instead if i call it through an IBAction (pushing a button from app) it works ?
Actually i can see from the log that the method is called in both cases but update data just with IBAction.
the method:
- (IBAction)void {
NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:#"1"];
[column setWidth:50];
[tableData addTableColumn:column];
[tableData reloadData];
[[column headerCell] setStringValue:#"aColumn"];
NSLog(#"Method called"); //The method is called in both cases
}
I can't find out what I am doing wrong.
(New to cocoa programming)
Thanks a lot !

Where did you call this programmatically? You might have called it before the view was loaded in an init method instead of something else like awakeFromNib.

I tried your code and got different results. It was called fine from code (and the table updated), but not from the button (and the log wasn't run either when attempting to call from the button).
The problem is the method name -- you shouldn't name a method void. Do you not get the error message in the console: "Could not connect the action void: to target of class AppDelegate"
The compiler won't even allow me to connect that method to the button (it looks like I can in IB, but I get that error message, and if I put the method in the .h file, it has no circle next to it that shows whether it's connected or not).

Related

why setStringValue call works in viewDidLoad and viewDidAppear but not in other methods?

I am trying to change the value of the label here.
Can anyone explain me why the following method call:
[_detailLabel setStringValue:#"this is new label value"];
works if I make the call from viewDidLoad and viewDidAppear methods, but it doesn't work in the method that I created:
-(void)changeLabelValue : (NSString *) newVal {
[_detailLabel setStringValue:#"this is new label value"];
NSLog (#"Hello from changeLabelValue method");
}
Please note that when I call this method from anywhere from my code, the NSLog message IS displayed but the value of the label is not changed...
Any help is deeply appreciated.
Pointing me to resource where I can learn more on this subject will also do the trick, and will be also deeply appreciated.
Regards, John.
Make sure that changeLabelValue: is being called after viewDidLoad is called (or the view controller has been displayed). If you call it before the view is loaded, _detailLabel will be nil since it hasn't been loaded yet.

(Cocoa Mac) NSWindowController showWindow allocates/initializes a new NSWindowController?

I have a class BrowserWindowController that extends NSWindowController. My app delegate has a BrowserWindowController that it allocates, initializes, and points an instance variable at when the app is launched. Then, it displays its window. The goal is to have a window from a NIB show up.
However, the code I am using ends up allocating TWO BrowserWindowControllers and initializes both. I have used the debugger to track down when BWC's initWithWindow method is called:
browser = [[BrowserWindowController alloc] initWithWindowNibName:#"BrowserWindow"]; //this calls initWithWindow as expected
[browser showWindow:nil]; //this allocates ANOTHER BWC and calls initWithWindow on it!
showWindow is making a new BrowserWindowController. I don't know what points to the new object it makes. It's a huge problem for me. Any way to get around this or make the window show up using a different method? Or could I at least get a pointer to the controller that showWindow creates for whatever reason?
Did you check the condition like this and try?
if !(browser)
{
browser = [[BrowserWindowController alloc] initWithWindowNibName:#"BrowserWindow"]; //this calls initWithWindow as expected
[browser showWindow:nil];
}
Worst solution ever. The problem was that I had a property in my controller called "owner" that was an NSString. NSWindowController already has an "owner" property, and I overlooked that. Somehow, that caused the NIB loader to make a second controller with no accessible pointer to it and do some other weird things.
So I renamed it, and it works now. Thank goodness... I was tearing my hair out with this problem.

Delegate gets called but the calling viewcontroller is released

Probably a noob question, but I cannot seem to get it right at the moment. I am working on an app where I have an Actionsheet for the confirmation of some basic things. However after the delegate is called for that Actionsheet my initial calling object is released (or not initiated).
In the delegate method I then want to call a method on that object but it just not do anything from that point.
The self.inviteSponsorsFromVC is not initiated anymore in this scenario and I want to call the saveSponsorWithEmail method from it. I cannot just reinitiate it, as the object had some objects in it, it has to use.
Everything works correctly if I just remove the actionsheet and call the saveSponsorWithEmail method directly without using a delegate.
This is my delegate method:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
//Get the name of the current pressed button
NSString *buttonTitle = [actionSheet buttonTitleAtIndex:buttonIndex];
if ([buttonTitle isEqualToString:NSLocalizedString(#"Send invitation", nil)]) {
ContactFromAddressBook *contactFromAddressBook = [self.tableData objectAtIndex:selectedIndex.row];
[self.inviteSponsorsFromVC saveSponsorWithEmail:contactFromAddressBook.email andName:contactFromAddressBook.fullName];
}
if ([buttonTitle isEqualToString:NSLocalizedString(#"Cancel", nil)]) {
NSLog(#"Cancel pressed --> Cancel ActionSheet");
}
}
My guess is that at in the delegate method the content of self.inviteSponsorsFromVC is nil. In Objective-C, when you send a message to nil the message is simply ignored (unlike C++, for instance, where you get a crash when you call a method on a NULL object).
As an experiment you can try either one of these:
If you use ARC, make the property self.inviteSponsorsFromVC a strong reference
If you don't use ARC, say [self.inviteSponsorsFromVC retain] at some point before you display the action sheet
Either way, what you need to do is to make sure that the object in self.inviteSponsorsFromVC is not deallocated before you invoke a method in it.
EDIT after your comment
The property declaration is good, it's got the strong attribute on it. In your InviteSponsorsFrom class, try to add a dealloc method and set a breakpoint there to see if the object is deallocated, and where the call comes from.
- (void) dealloc
{
[super dealloc];
}
Also make sure that an instance of InviteSponsorsFrom is created in the first place. I assume you have an initializer somewhere in that class where you can set a breakpoint and/or add an NSLog statement to make sure that the instance is created.

how to call a method from a class in another class

I'm working to a new app for mac osx where i'm using a drag and drop system to let the user to input some files [this part works well] and i have a tabelView where i would like to display the paths of files inputed.
I have the next method in tabelViewController.m:
-(void)add{
NSLog(#"da");
[list addObject:[[Source alloc] init]];
[tableView reloadData];
}
In the DropView.m i included the tabelViewController.h and i'm trying to call the add method but it does nothing:
#import "TableViewController.h"
.....
- (void)concludeDragOperation:(id<NSDraggingInfo>)sender{
[self setNeedsDisplay:YES];
TableViewController *tvc;
[tvc add];
}
Can someone to figure out why it doesn't do anything ?
Edit1:
Ok after I fallow the answers, my concludeDragOperation method looks like this:
- (void)concludeDragOperation:(id<NSDraggingInfo>)sender{
[self setNeedsDisplay:YES];
TableViewController *tvc = [[TableViewController alloc] init];
[tvc add];
[tvc rD];
}
rD is a method from tableViewController which contain the reloadData method.
But it doesn't want to work it don't reload the table view.
Any ideea ???
tvc needs to point to an actual object. [[tvc alloc] init]
Otherwise you are simply calling add on nil. This doesn't cause your program to crash as you might expect in other languages. Try it out and see what happens.
it seems as if you missed a great chunk regarding how OOP and Objective-C work (seriously, no offense there).
What link is there between DropView.m and tableViewController.h do you have?
By typing TableViewController *tvc; all you are doing is creating a pointer. You are neither creating an object nor pointing to an object, you have just simply created a pointer that can eventually point to an object in memory of type tableViewController.
Solution:
What you will need to do, is to somehow create a link between the two classes. For instance, you could create a custom delegate method for DropView that could communicate with any class who uses that custom DropViewDelegate methods. So, you could create a delegate method that tells objects that follow that delegate protocol that you just concluded a drag operation. A tutorial how to do so can be found at my blog [it's a permalink].
I am happy to post code, or you can read it on my blog. Good Luck.

Why can I not reset a text field within an IBAction associated with it?

I have an IBAction called keyboardResponse associated with a text field called myTextFieldIBOutlet via the "Editting Changed" event handler in the xib:
- (IBAction)keyboardResponse:(id)sender
{
// process this single character - function I wrote else where that works fine.
[self processSingleCharacter:myTextFieldIBOutlet.text];
// clear input text
myTextFieldIBOutlet.text = #"";
}
It's supposed to clear the input after the user types something into it.
I get a run time error with this code in iOS Simulator:
Thread 1: EXC_BAD_ACCESS (code=2, address=0xbf7fff0c)
Why? I had synthesized the IBOutlet myTextFieldIBOutlet already.
if myTextFieldIBOutlet is synthesized, you should change the last line to:
self.myTextFieldIBOutlet.text = #"";
If the textfield you want to clear is the same control that calls this action, you can also use the sender variable you are sending
[sender setText:#""];