Calling external method actually calls other method - iphone

I must be asleep already or something because I'm seeing weird things.
I've got a class, called ListSorter (.h/.m), which has 2 extern methods.
The .h looks like:
#interface ListSorter : NSObject {
BOOL eersteKeer;
Menu_Versie_DrieAppDelegate *appDelegate;
}
-(void)convertList;
-(void)addItemToAlertList:item;
-(void)addItemToHistoryList:item;
In an other class, I've imported ListSorter.h in the .h-file, and made an instance of it:
#import "ListSorter.h"
#class ListSorter;
#interface CloseIncController : UIViewController {
ListSorter *sorter;
}
#property (nonatomic, retain) ListSorter *sorter;
So, in the .m-file, I've got:
#synthesize sorter;
...
//Somewhere down in an IB-action
[sorter addItemToHistoryList:keuze];
I NSLogged both addItemToAlertList and addItemToHistoryList, but it always calls addItemToAlertList. Why's that?

you can add multiple action to a button, check if you don't add addItemToAlertList and addItemToHistoryList to the same button

Solved it temporarily by creating two classes, both with one of the methods. My guess is the class didn't get allocated properly.

Related

How to use #protocol in AppDelegate iPhone app?

I am working in iPhone app with 5 screens. I want to refresh the values in the screen 4th in UITabBarController. I have added #protocol in AppDelegate but it is not calling. This is the first time am using #protocol could you please help me to solve this issue,
In AppDelegate.h
#protocol ReloadViewControllerDelegate <NSObject>
-(void) refreshViewController:(NSString *)result;
#end
id refreshViewControllerDelegate;
#property (nonatomic, retain) id refreshViewControllerDelegate;
and i have synthesized.
In AppDelegare.m
#synthesize refreshViewControllerDelegate;
if ([refreshViewControllerDelegate conformsToProtocol:#protocol(ReloadViewControllerDelegate)])
{
[refreshViewControllerDelegate performSelectorOnMainThread:#selector(refreshViewController:) withObject:#"YES" waitUntilDone:NO];
}// Control not come inside of if Condition.... From here i want to update the fourthViewController..
But control not go inside of the if condition. Could you please guide me where am doing wrong?
In my 4th ViewController.h
#import "AppDelegate"
#interface fourthViewController : UIViewController <ReloadViewControllerDelegate>
In my 4th ViewController.m
-(void) refreshViewController:(NSString *)result
{
NSLog(#"Result : %#", result);
}
Can anyone please help me to do this? Thanks in advance.
You need to declare your delegate like this:
#property (nonatomic, weak) IBOutlet id<ReloadViewControllerDelegate> delegate;
The id will work, but by using the <>, you can make sure that the delegate you assign is actually implementing the protocol, you might still have to make sure it responds to selector but that is only if some methods are declared as
#optional
make sure you synthesize it and most important make sure you set it, and it is not nil.
You're getting a warning because you are typing your delegate as an id. An id is a generic type, which means the compiler has no idea of what methods or properties might be available. In order to remove your warning, declare your delegate to be an NSObject:
#property (nonatomic, retain) NSObject <ReloadViewControllerDelegate> *refreshViewControllerDelegate;
By declaring as an NSObject, the compiler now knows about all the methods NSObject has, which will then allow you to call:
-performSelectorOnMainThread:withObject:waitUntilDone:
on your delegate without warnings. Good luck!
Try this:
#protocol ReloadViewControllerDelegate <NSObject>
-(void) refreshViewController:(NSString *)result;
#end
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (weak) id <ReloadViewControllerDelegate>refreshViewControllerDelegate;
#end
In AppDelegate.m
#implementation AppDelegate
#synthesize window, refreshViewControllerDelegate;
...
here Tab4ViewController is name of class.
if ([Tab4ViewController conformsToProtocol:#protocol(ReloadViewControllerDelegate)])
{
[refreshViewControllerDelegate performSelectorOnMainThread:#selector(refreshViewController:) withObject:#"YES" waitUntilDone:NO];
}
...
#end
#import "AppDelegate.h"
#interface Tab4ViewController<ReloadViewControllerDelegate>
...
#end
#implementation Tab4ViewController
...
appDelegate.refreshViewControllerDelegate = self;
...
#end
You are calling this code:
if ([refreshViewControllerDelegate conformsToProtocol:#protocol(ReloadViewControllerDelegate)])
But refreshViewControllerDelegate is this:
id refreshViewControllerDelegate;
conformsToProtocol checks to see if the object declares that it conforms to the protocol, which yours does not. If you want to specify conformity to a protocol you need to:
id<ReloadViewControllerDelegate> refreshViewControllerDelegate;
EDIT
OK, on the performSelectorOnMainThread problem... That method is provided in a category for NSThread, and is not declared in the NSObject protocol. So, if you want to call that, then you need to declare your type as NSObject, which conforms to your protocol.
NSObject<ReloadViewControllerDelegate> refreshViewControllerDelegate;
EDIT
OK, it looks like this is not a simple question about using a protocol, but a full tutorial. Since SO isn't the place for such, I'll try to give a brief one...
A protocol is an interface declaration.
#protocol ReloadChatViewControllerDelegate <NSObject>
- (void)refreshViewController:(NSString *)result;
#end
That says there is a new protocol in town, with the name ReloadChatViewControllerDelegate and it also conforms to the NSObject protocol. Any class that adopts the new protocol must provide an implementation of refreshViewController. You can make a protocol method optional, by putting in an #optional section.
#protocol ReloadChatViewControllerDelegate <NSObject>
- (void)refreshViewController:(NSString *)result;
#optional
- (void)optRefresh;
#end
Now, let's leave the adoption of the protocol for later. Say you are writing generic code, and you just want to know if the object you are given conforms to the protocol, and if so, invoke a method on it. Something like...
#interface Bar : NSObject
#property (nonatomic, weak) NSObject<ReloadChatViewControllerDelegate> *refreshViewControllerDelegate;
- (void)blarg;
#end
Now, the Bar class is providing a delegate property, so that it can be give some object that will help it do some work. However, that delegate object must at least be an NSObject, and conform to the ReloadChatViewControllerDelegate protocol.
Now, ObjC (and C) is quite permissive, so you can force an object to be any type you want, but then you deserve the crash you get. Now, when blarg is called, the delegate is notified to do some work.
Since the property type of the delegate already says it conforms to the given protocol, there is no need to check for conformity. We can just call the delegate method. Note that we must see if the object implements any optional protocol methods.
#implementation Bar
#synthesize refreshViewControllerDelegate = _refreshViewControllerDelegate;
- (void)blarg {
// Do something, then invoke the delegate
[self.refreshViewControllerDelegate
performSelectorOnMainThread:#selector(refreshViewController:)
withObject:#"YES"
waitUntilDone:NO];
if ([self.refreshViewControllerDelegate respondsToSelector:#selector(optRefresh)]) {
[self.refreshViewControllerDelegate optRefresh];
}
}
#end
However, if you want to be generic, and accept any object as a delegate (maybe you want to make it optional that the delegate conforms to some given protocol), then you can accept a plain id and then check to see it it conforms. In that case, you could declare your delegate as just an id (or some other type).
#property (nonatomic, weak) id refreshViewControllerDelegate;
Now, in your code, you need to check for conformity.
- (void)blarg {
// Do something, then invoke the delegate
if ([self.refreshViewControllerDelegate
conformsToProtocol:#protocol(ReloadChatViewControllerDelegate)]) {
[self.refreshViewControllerDelegate
performSelectorOnMainThread:#selector(refreshViewController:)
withObject:#"YES" waitUntilDone:NO];
if ([self.refreshViewControllerDelegate
respondsToSelector:#selector(optRefresh)]) {
[self.refreshViewControllerDelegate optRefresh];
}
}
}
OK, now you have a protocol defined, and you have code that calls methods on the protocol. Two caveats.
First, the delegate has to be set to an object. nil will respond false for any method, so it will of course not conform, nor do anything when sent any message.
Second, you have to make sure that your delegate declares conformity to the protocol. Just implementing the methods is not conformity. If a class does not explicitly specify that is conforms to a protocol, then conformsToProtocol will return false, even if it implements the methods of the protocol.
So, let's specify some class that will act as our delegate by conforming to the protocol.
#interface Foo : NSObject<ReloadChatViewControllerDelegate>
- (void)refreshViewController:(NSString *)result;
#end
#implementation Foo
- (void)refreshViewController:(NSString *)result {
NSLog(#"Look, ma, I'm refreshed with %#", result);
}
#end
It conforms to the protocol, provides an implementation for the mandatory method, and omits the optional one.
Now, if you ran this code, you should see that marvelous code in all its splendor.
Foo *foo = [[Foo alloc] init];
Bar *bar = [[Bar alloc] init];
bar.refreshViewControllerDelegate = foo;
[bar blarg];

Objective C - Make iVars hidden

Here's my question.
Let's say I have a class called WebServiceBase.h. And I need to add a iVar in to that class called NSString *requestData. But I don't need to add that iVar in to the header file and make it visible to the external people. (If I'm distributing this as a class library)
Also I need to be able to access this requestData iVar, within the other classes that is extended from the WebServiceBase.h. (These extended classes are written by me. Not from the external people)
I tried with declaring the requestData iVar within the class extensions. But then it's not visible to the extended classes.
Any solution for this? I need to protect my data and make it hide from the external world.
You can define your ivars as protected via the #protected keyword, meaning that your class and all subclasses can access it without any problem, but the compiler won't allow this for other classes which don't inherit from your base class:
#interface Foo : NSObject
{
#protected
NSObject *a;
}
Its as simple as that and already gives you all the safety you can get from Objective-C.
You can have an ivar definition block in the #implementation block.
there are 2 ways , you can choose one you like.
1).h file
#interface YourClass
{
}
.m file
#interface YourClass ()
#property (nonatomic, retain) NSString *title;
#end
#implementation YourClass
#synthesize title;
//your method
2) .h flie
#interface YourClass
{
}
.m file
#implementation YourClass
{
NSString *title;
}
//your method
Declare a class extension that defines the ivar in another .h file. Call it something like myclass-private.h. Then import that header in both your main class your subclasses.

How to use delegates in ios 5

I need to use a delegate object in an iOS application. I have declared the delegate as this:
In the class where the function is defined:
#interface OOObjectCommandInterface : NSObject<OOCameraControllerDelegate>
In the class where the function must be invoqued:
(In de .h file)
#protocol OOCameraControllerDelegate
- (void)drawFrame:(CVImageBufferRef) imageBuffer:(BOOL)flip;
#end
and
#interface OOCameraController : UIViewController
{
...
id<OOCameraControllerDelegate> delegate;
}
#property (nonatomic, readwrite) id<OOCameraControllerDelegate> delegate;
Aditionally, where the second class is initialized:
_hardwareController.delegate = [OOObjectCommandInterface ocInterface];
where _hardwareController is an instance of OOCameraController class.
So, when I try to invoque the delegate object, I do this:
[delegate drawFrame:imageBuffer:flip];
but the function is not executed. Any idea?
P.D.: The function I am calling is a singleton class. Could be any problem there?
Have you set delegate to self in the second class? Create an object in the second class like
#property (nonatomic, readwrite) id<OOCameraControllerDelegate> delegate;
and then [_hardwareController setDelegate:self];
By definition, a singleton is a design patron to access an object, unique, that only can be created 1 time (first get_instance you do). With get_instance, you can access from everywhere, to the functions inside the singleton, so, Why you are not using it directly?
Write something like [[MySingletonClass get_instance] FunctionThatIWantToUse:...]; And don't use a delegate

Problems referencing iVar in inner class

I have a class called MyClass which has a small nested inner class called MyInnerClass. The implementation file looks like the following (and also contains an ivar of the nested inner class) :
#class MyInnerClass;
#interface MyClass
{
MyInnerClass *myInnerClassIvar;
}
#property(nonatomic, retain) MyInnerClass *myInnerClassIvar;
#end
Then in the implementation file, I implement both MyClass and MyInnerClass. Looks like the following:
#interface MyInnerClass
{
iVar *x;
}
#property(nonatomic, retain) iVar *x;
#end
#implementation MyInnerClass
#synthesize x;
...
#end
#implementation MyClass
#synthesize myInnerClassIvar;
...
#end
I am now creating a subclass for MyClass, and in it I'm trying to make a call like this:
self.myInnerClassIvar.x
And I'm getting the following message:
Property x cannot be found in in forward class object MyInnerClass *
Am I forgetting something? Haven't implemented an inner class before, see no reason why this shouldn't work.
UPDATED: I moved the interface of MyInnerClass to the .h of MyClass and everything works. Is this a good solution?
I believe that Objective-C does not have inner classes in the sense that you are trying to implement. See SO. But regarding your question...
in MyClass.h there is no mention of the iVars of MyInnerClass - it is a forward definition, i.e. #class MyInnerClass therefore MySubClass has no reference point for x.
If you define two classes MyClass & MyInnerClass (probably a bad thing to name it that considering...) - have them in two separate .h files and two separate .m files (ie. as normal). Make an #property in MyClass of type MyInnerClass. Then in MySubClass you need to import both MyClass & MyInnerClass.
I moved the interface of MyInnerClass into the .h file of MyClass like following:
MyClass.h
#class MyInnerClass;
#interface MyClass
{
MyInnerClass *myInnerClassIvar;
}
#property(nonatomic, retain) MyInnerClass *myInnerClassIvar;
#end
#interface MyInnerClass
{
iVar *x;
}
#property(nonatomic, retain) iVar *x;
#end
I'll wait before I check this off as the answer because based on the previous answer, I know there is some skepticism. The only reason I tried this is because I saw it in the Apple example SimpleTextInput, except in that one the entire inner class is in the .m file. Anyway, would be interested to hear what people have to say about this, if it might incur unwanted side effects later or if its ok.

Trouble with error 'cannot find protocol declaration'

I got SO questions also same as this and I tried with solution but still its not working for mine so asked this again.
This is my VCWithProtocol.h
#protocol mydemoDelegate
#optional
-(void)demoDelegateMethodWithSuccess:(BOOL)yesOrNo;
#end
#interface VCWithProtocol : UIViewController
{
id<mydemoDelegate>mydelegate;
}
#property (nonatomic,assign)id<mydemoDelegate>mydelegate;
VCWithProtocol.m
`#synthesize mydelegate`
This is my class where I am trying to use my Delegate
#class VCWithProtocol;
#interface VCTOUseDelegate : UIViewController <mydemoDelegate> //here is where it shows error with cannot find protocol declaration
VCTOUseDelegate.m
VCWithProtocol *obj = [[VCWithProtocol alloc] init];
obj.mydelegate = self;
I tried with Importing VCWithProtocol but not working as well
Instead of #class VCWithProtocol; write #import VCWithProtocol.h
And some good practice Use capital letter for first character of any class name and protocol.
e.g. MyDemoDelegate and avoid retaining delegate use
#property (nonatomic,assign)id<mydemoDelegate>mydelegate;
Synthesize your mydelegate, and call
[self mydelegate];
You need to add #import "VCWithProtocol.h" to the top of your .m file.
#property (nonatomic,**weak**)id<mydemoDelegate>mydelegate;
delegate always needs weak link