objective c : hand over delegate to other class - iphone

I am here confronted with a certain problem. I have a protocol which states a method, that returns the datasource for my tableviews. The datasources are generated by one class, for 3 tableviews. If you tap on one cell, you get to the next tableview with a different source and so on (I think you get the point).
Everything works fine for the first tableview, but as I hand over the deletage to the next tableview I still do not get the datasource for the second. Do I have to release the delegate at a certain point? And if I have to, how do I get it back, when the navigationbarbuttonitem is tapped on...?
Tell me if you have any ideas.
EDIT:
if ([Where isEqualToString:#"System"])
{
if ([exchangeDelegate respondsToSelector:#selector(getNewDataSourceForSystem:)])
{
[exchangeDelegate getNewDataSourceForSystem: [controlDelegate setBranchNavigation:What]];
}
}
else if ([Where isEqualToString:#"User"])
{
if ([exchangeDelegate respondsToSelector:#selector(getNewDataSourceForUser:)])
{
[exchangeDelegate getNewDataSourceForUser: [controlDelegate setLeafNavigation:What]];
}
}
if ([exchangeDelegate respondsToSelector:#selector(getNewDataSourceForCostumer:)])
{
[exchangeDelegate getNewDataSourceForCostumer: [controlDelegate setRootNavigation]];
}
each respondToSelector goes to a different class.
EDIT:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Costumers getNewDataSourceForSystem:]: unrecognized selector sent to instance 0x8a3b0e0'
Thats what I get as an exception when I leave out respondsToSelector:#selector.

Have you called -[UITableView reloadData] to inform it about invalidation of its current state?
And have you overloaded you delegate setter method in order to also fetch and set the new datasource and delegate as needed? Probably something like this:
-(void)setDelegate:(id<MYDelagate>)delegate;
{
myTableView.dataSource = [delegate tableViewDataSource];
myTableView.delegate = [delegate tableViewDelegate];
_delegate = delegate;
}

So, as it seems, using a singleton is the proper way to store my data for my views:
I created a singleton.
The singleton holds my 3 different data-arrays.
The delegate sends the new arrays to the singleton.
I am fetching the data from the views via the singleton.
As simple as it is ... thank you guys for your inspiration :-)

Related

block delegate methods of class in iphone

I am having a problem I am working on a class which is subclass of UITextField.
Which will be used in many classes further.
But I don't want to let user to use it's delegate methods in any way.
Is there any way to do this ?
Override setDelegate: so that it throws an exception or logs an instruction on what to do. That way your API users will know what's actually going on.
-(void) setDelegate: (id <UITextFieldDelegate>) delegate
{
NSLog(#"*** Use the blocks API instead of calling %s", __PRETTY_FUNCTION__);
[self doesNotRecognizeSelector: _cmd];
}
Override the -setDelegate: method such that it never actually sets a delegate. You can just provide an empty method that fails to call super:
-(void) setDelegate:(id<UITextFieldDelegate>) delegate
{
// this method intentionally empty to prevent a delegate from ever being set
}

UIPickerView on Separate Page

I am working on an iPhone app. Initially, I had my pickerview in the same screen so this was just a one page app. After skinning it i realized that i want the pickerview on it's own separate page. So i did that. However, my pickerview originally would update uilabels and other objects on that same page. How can I have my pickerview access those objects from it's new view?
- (IBAction)ShowPickerAction:(id)sender {
if (self.theView == nil) {
theView = [containerView initWithNibName:#"containerView" bundle:nil];
theView.parentView = self;
}
self.theView.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:self.theView animated:YES];
}
That is the method I am using to call my new view. But line 3 of the above code gives me the error "No known class name for selector initWithNibName:bundle". I think that error is related to something that i did wrong in my header file. My new class is called containerView. So i did this in my header:
#interface ViewController : UIViewController {
containerView *theView;
But that gives me the error "Unknown type name containerView" even though i do have a class named containerView!!
Look into uiappdelegate protocol or try passing values to through a static function to the previous page.
Use a delegate to pass information back and forth to the view object that instantiatrd the picker view. You want to keep your code coupling as loose as possible, especially if you might like to drop it into your next project. Using a delegate and/or blocks are some of the best ways.

Strange memory address resulting in BAD_ACCESS

I'm trying to wrap my head around a strange problem in my iPad app. It's a pretty simple app, only one root view controller with a little board game inside.
Sometimes, seemingly at random, the app freezes and I get a BAD_ACESS on a delegate reference I use in one of my classes. I've been solving BAD_ACCESS-problems for a long time, but this is very strange. The object the delegate is referring to is the root view controller, and that should never b released. I put a log line in the -(void)dealloc method and that never occurs. I even tried to over retain the object but it still disappears.
Even if I run the app in the profiler with NSZombie detection on, the profiler just stops when this happens. Doesn't show any results whatsoever.
Another strange thing I noticed was the memory address. If I log it like NSLog(#"%p", delegate); i get "0x1" as a result. A nil pointer is 0x0 so testing for if(delegate) does return true even though the object has vanished. And even if the object itself was deallocated, the memory address would still be intact?
The problem only occurs after some use, between like 15 and 45 sec.
Doed someone know how to tackle this problem? I'd be greatly thankful.
This is how the delegate is assigned. The _delegate is the root view controller which is always active.
-(id)initWithDelegate:(NSObject <TheGameDelegate>*)_delegate level:(int)_level;
{
self = [super init];
if(self != nil)
{
delegate = [_delegate retain];
...
Here is where it crashes:
-(void)countdown:(NSTimer*)timer;
{
time -= 1;
if(delegate) // this is always true
{
NSLog(#"%p", delegate); // this prints a normal memory address until right before crash when it prints "0x1"
[delegate theGameTick:self]; // accessing deleagte gives BAD_ACCESS
}
...
Thanks in advance!
imo, your delegate implementation is weird.Retaining delegates is not the good idea. Try adding to the header:
#property (nonatomic, assign) id delegate and then the method would look like
-(id)initWithDelegate:(id)_delegate level:(int)_level;
{
self = [super init];
if(self != nil)
{
self.delegate = _delegate;
...}
as well as in further methods you reference to self.delegate.(you can add the required protocol as well, i skipped it for clearer code)

how to solve unrecognized selector sent to instance?

I have a uitableview 'A' which has cells, on clicking one of the cell, it needs to push another table view 'B'. and now when a cell is clicked in 'B', its needs to open a simple view.
I have managed to display both the tables in two different views. but when a cell is clicked in the menu B. it hangs and shows the below message
> unrecognized selector sent to > instance
could someone please tell me how do i solve this.thanks
Please find below my code
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger row = [indexPath row];
NSLog(#"entering the if loop libdecripviewcontoller");
if(self.libraryDescripViewController == nil){
NSLog(#"its creating new instance of libdecripviewcontoller");
LibraryDescripViewController *aLib = [[LibraryDescripViewController alloc] initWithNibName:#"LibraryDescripView" bundle:nil];
self.libraryDescripViewController = aLib;
[aLib release];
}
libraryDescripViewController.title = [NSString stringWithFormat:#"%#",[libraryMenu objectAtIndex:row]];
ULS1AppDelegate *delegate = [[UIApplication sharedApplication] delegate ];
[delegate.searchLibNavController pushViewController:libraryDescripViewController animated:YES];
}
Please find the output below
2010-06-27 20:13:15.521 ULS1[1020:207]
entering the if loop
libdecripviewcontoller 2010-06-27
20:13:15.533 ULS1[1020:207] its
creating new instance of
libdecripviewcontoller 2010-06-27
20:13:15.541 ULS1[1020:207] *
-[LibraryMenuTabViewController setLibraryDescripViewController:]:
unrecognized selector sent to instance
0x3c2ec70 2010-06-27 20:13:15.554
ULS1[1020:207] * Terminating app due
to uncaught exception
'NSInvalidArgumentException', reason:
'*** -[LibraryMenuTabViewController
setLibraryDescripViewController:]:
unrecognized selector sent to instance
0x3c2ec70' 2010-06-27 20:13:15.558
ULS1[1020:207] Stack: ( 29303899,
2512004361, 29685819, 29255286,
29107906, 14755, 3050054, 3033220,
287146, 29088448, 29084744, 37393941,
37394138, 2777007, 11184, 11038 )
You can get more information about where the error is happening by opening your debugger window, clicking on "Show Breakpoints", and setting the following two breakpoints:
[NSException raise]
objc_exception_throw
Now when your app is about to crash, the debugger will usually show you exactly what line of code is causing the problem.
For this reason, it's good practice to have these breakpoints on every app you are developing.
It seems that you are calling "self.libraryDescripViewController = aLib" which is another way of writing [self setLibraryDescripViewController:alib].
The most likely cause of this would be in that you haven't declared the method setLibraryDescripViewController in your class.
Hope this helps.
There is way too little information here to diagnose exactly whats causing this, but one thing is certain. The method you are sending to the object is not defined for that object. Please post the code thats causing the error and the .h and .m files for the simple view you are talking about.
You probably need to set the class of the view controller in IB to LibraryDescripViewController. Double click the LibraryDescripViewController.xib file in xcode and when IB opens, in the identity view of the file's owner set the class to LibraryDescripViewController

how do i add two delegates to a ui element at run time?

im trying to implement some behaviors when a mapview element scrolls... by coding a delegate for the scrollview inside of a mapview.
so, right now, i got a pointer to the scroll view used by the map view in my code.
however, i wish to set the delegate of this scroll view inside the map view, but the issue is that the mapview already sets up a default delegate for this scroll view inside the map view.
can i make my delegate implement all of the messages of the protocol, explicitly sending them to the mapview's default delegate while also implementing my own behaviors?
how else can i go about adding my own delegate behavior, to an already existing default delegate....?
thanks everyone,
michael
You could just get the existing delegate and save a reference for yourself:
origDelegate = [theView delegate];
And then set the object you want as the delegate:
[theView setDelegate:self];
Then when getting a delegate message, call the same method on origDelegate, modify the response if you want to (or if necessary), and then return the modified response:
- (BOOL)shouldViewDoSomething:(id)theView
{
BOOL result = [origDelegate shouldViewDoSomething:theView];
if (decision1)
{
result = !result;
}
return result;
}