Why my custom delegate method does not receive the call? - objective-c

I would like to send the message from HelloWorldLayer, and receive it in ScoreLayer, in order to update the label. The CCLOG(#"///addNewScore"); works fine, but then updateScore, in ScoreLayer, does not receive the call, would you know why? Here's my code : (edit: i tried with "retain" in #property, but nothing changes) :
#interface HelloWorldLayer : CCLayer
{
//...
id<ScoreDelegate>delegate;
}
#property (nonatomic,retain) id <ScoreDelegate> delegate;
#implementation HelloWorldLayer
#synthesize delegate;
//...
-(void)addNewScore:(int)num{
CCLOG(#"///addNewScore");//works fine
[delegate updateScore:num];
}
#import <Foundation/Foundation.h>
#protocol ScoreDelegate
-(void)updateScore:(int)num;
#end
#interface ScoreLayer : CCLayer <ScoreDelegate>{
//...
}
-(void)updateScore:(int)num{
CCLOG(#"hello");//DOES NOT WORK
}
#end
Thanks a lot

I suspect that the ScoreLayer is being released before your call. I'm not too familiar with assign, I have only written ARC Objective-C; but I think it is roughly the same as weak (as it should be for delegates). This means that in order for that pointer to be valid, someone else in the application needs to "own" the ScoreLayer.
Now, that being said, I've only assumed that you are properly connecting the two objects in the first place. There isn't code posted which shows that, but this matter of a possibly-released ScoreLayer is important enough to keep in mind either way.

You would declare that protocol (delegate method) in the interface file of HelloWorldLayer. You would then put the delegate method inside ScoreLayer.m:
-(void)updateScore:(int)num {
// Do something
}
The way it is now, you declared the protocol in the wrong class.

Related

is this a good use of the copy method for an NSArray?

you have a class or ViewController using model/service class like so:
#interface MainViewController : UIViewController <TweetServiceDelegate> {
NSArray *_tweets;
}
#property (nonatomic, strong) TweetService *tweetService;
#end
#implementation MainViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.twitterService queryForLatestTweets];
}
// delegate methods the tweetservice calls back after async getting data
- (void)querySucceededWithTweets:(NSArray *)tweets {
_tweets = [tweets copy];
}
#end
The reason I ask because the Service has a weak reference to the delegate, which is the ViewController.
So I know with ARC you don't want 2 things that use each other to both have a strong reference, so if it's weak but the ViewController retains the NSArray, then the Service wouldn't be collected once it went out of scope, assuming the service did go out of scope but the ViewController didn't
#interface TweetService
#property (nonatomic, weak) id<TweetServiceDelegate> delegate;
#end
#implementation TweetService
- (void)queryForLatestTweets {
// do the query with AFNetworking, when succeed block fires, call the delegate
[self.delegate querySucceededWithTweets:arrayOfTweets];
}
#end
I would say this is rather the recommended way of doing this sort of things. The service is held strongly by the controller that needs it, but the service holds the controller only weakly as a delegate because it does not need to know what its delegate is -- or even if it exists -- to function.
When the service returns something through delegate methods back to its delegate, the delegate should claim ownership of the data. The preferred way is to copy, since the delegate does not know anything about the return value's lifecycle. copy makes a new instance that can be think as a "snapshot" of the data. Working on this "snapshot" guarantees that your data are not modified when you don't want them to. This effectively decouples the service and the delegate.
A side note: Your self._tweets won't work because _tweets is an instance variable, but the dot syntax expects a property. _tweets = [tweets copy]; would be correct.
I will say YES it is good to use because...
if you are not copying that array just simply assign _tweet = tweet array.
then if you are doing change in any one of the array it will affect to other array..
so Yes i will suggest you to use COPY method such time...
Thanks.

Update UILabel text from another class in Objective-C

I have a method implemented in the ViewCotroller class to set the message to a UILable in that class.
-(void)setAuthenticationMessage:(NSString *)message{
//lblStatus is the UILabel
lblStatus.text = message;
}
I'm accessing this method from another class to set the message. Though code executes correctly this message didn't update. I tried it by executing this method in a different thread. But that was also unsuccessful. Can anyone help me to figure out the issue?
What are lblStatus's memory management properties? Your naming convention alone leads me to believe that it is something to do with this. Usually you refer to instance variables as:
_lblStatus or self.lblStatus
use #protocol & delegates to access another class refer this link example example2
Use the delegate design pattern (google it). Example:
//In the updating class .h
#protocol LabelChangerDelegate <NSObject>
-(void)handleLabelChangeMessage;
#end
#property (assign, nonatomic) id <LabelChangerDelegate> delegate;
//In the updating class .m
-(void)changeLabelInOtherClass{
if (self.delegate != nil && [self.delegate respondsToSelector:#selector(handleLabelChangeMessage)]) {
[self.delegate performSelector:#selector(handleLabelChangeMessage)];
}
} else {
NSLog(#"Delgate doesn't implement handleLabelChangeMessage");
}
//In the view controller .h
<LabelChangerDelegate>
-(void)viewDidLoad{
//set the delegate to self
}
//In the view controller .m
-(void)handleLabelChangeMessage{
self.label.text=#"I changed through delegation";
}
Another option is to use NSNotificationCenter

Error in protocol declaration

I am getting an error as:
protocol declaration not found
I couldn't find out what's the reason. Now I am using ARC. I doubt that the issue is due to that. Here is the code I am using for protocol declaration
//This is the first page we are declaring the Delegate
.h
#protocol ImageDelegate
#optional
-(void)ImageSelected:(UIImage *)ImageName;
#end
#interface GetAddedMovieList : UIViewController<UITableViewDataSource,UITableViewDelegate>{
id<ImageDelegate> delegate;
}
#property(nonatomic, strong)id<ImageDelegate> delegate;
#end
.m
#synthesize delegate;
//This is page in which i tried to set delegate. Here I am getting the error.
#interface ImageEnlarge : UIViewController<ImageDelegate>{
IBOutlet UIImageView *imgEnlarge;
NSString *stgImageName;
}
I see several (possible) issues in your code.
#property(nonatomic, strong)id<ImageDelegate> delegate;
delegates should be weak. GetAddedMovieList do now own the delegate by any mean and therefore shouldn't have an impact on its life cycle.
#synthesize delegate = delegate;
By default #synth uses either ivar_ or _ivar lately. With the latest LLVM #synth aren't necessary anymore btw, neither ivars.
#synthesize outside an #implementation ?
Have you checked your #imports?
It's probably an import loop. Do you #import the correct file for where you are using the protocol? And are you importing that file in the protocol file? If so then you have an import loop. Use forward declaration in the protocol's header instead and that should solve it. (#class)
You are putting an #interface on a .m file, are you trying to create a private #interface? With an IBOutlet declared there?
After seeing your edit, I am guessing there is only missing an import on the .h of your ImageEnlarge class.
Try like it.
#protocol ImageDelegate<NSObject>
#optional
-(void)ImageSelected:(UIImage *)ImageName;
#end
And also add this property.
#property(nonatomic,assign)id<ImageDelegate> delegate;
I think it will be helpful to you.

How to call a delegate's function without getting the "instance method not found" warning in ios?

In the apps I worked on, I often found such lines of code
[delegate aFunction];
that generated the "instance method "aFunction" not found (return type defaults to id)" warning
Now, I did a bit of research on SO and found out that the warning can be removed by declaring the function for cases when you call it on self ([self aFunction];), but none of the answers said anything about my case, when I use a delegate.
So, long story short, what can I do to correctly call a delegate's method inside another class?
Things appear to work fine, so this is not a major issue, but a warning means I'm not doing something completely correct so I would like to learn what's the best practice for such cases
Thank you for your help in advance!
So, if I'm understanding you correctly, your issues can be taken away by declaring your protocol as follows:
#class SomeClass;
#protocol SomeClassDelegate <NSObject>
#required
- (void)thisObjectDidSomething:(SomeClass*)instance;
#optional
- (void)thisObjectDidSomethingUnimportant:(SomeClass*)instance;
#end
Then your delegate ivar and property look like this (use assign instead of weak if you're not using ARC):
#interface SomeClass () {
__weak id<SomeClassDelegate> delegate_;
}
#property (weak) id<SomeClassDelegate> delegate;
And in the .h file of any class that's going to implement that protocol, do this:
#interface TCReader : NSObject <SomeClassDelegate> {
}
Since it's safe to call selectors on nil, for required methods, you can just:
[self.delegate thisObjectDidSomething:self]
But for optional methods, you'd better:
if ([self.delegate respondsToSelector:#selector(thisObjectDidSomethingUnimportant:)]) {
[self.delegate thisObjectDidSomethingUnimportant:self]
}
The main point here is that by declaring and making use of a protocol, you let XCode know that those methods are defined for objects implementing the protocol. If you require that your delegate implement that protocol, then Xcode knows that your delegate has those methods defined.

Property/Synthesize errors

Sorry to keep asking basic questions here but I don't know where else to go. Wrote some code with a slider, textfield and buttons for incrementing the slider to demonstrate key value coding. Everything worked find. The next step was to use 'property' and 'synthesize' in place of the accessor and setter methods;
#import <Foundation/Foundation.h>
#interface KVCController : NSObject {
int fido;
}
#property(readwrite, assign) int fido;
#end
~~~~~
#implementation KVCController
#synthesize fido;
- (id)init{
self = [super init];
if (self) {
// Initialization code here.
[self setValue:[NSNumber numberWithInt:5] forKey:#"fido"];
NSNumber *n = [self valueForKey:#"fido"];
NSLog(#"fido = %#", n);
}
return self;
}
~~~~~~~
#end
I get an incomplete implementation error on #implementation KVCController. If I put the get and set methods for 'fido' in it clears up.
The second error occurs with #synthesize fido;. It says property must be declared in the implementation. Everything is copied correctly out of the book and near as I can tell, it looks just like all the other uses of property and synthesize I have looked at. Anyone have any ideas on what I am missing or doing wrong?
Xcode 4.1 automatically creates a delegate class which I usually ignore if I am not working on delegates. I created my own class for the KVC exercise and just added the property/synthesize declarations to it with appropriate modifications and got the errors. I just put the property/synthesize declarations into the delegate class, moved my IBAction code to the appropriate places, redid the bindings, and erased the class I created and everything worked fine. Do property/synthesize declarations need to be treated like delegate material?
incomplete implementation means you have a -(void)something that may be defined in your header that you are not using in your #implementation. Make sure that you do not have any unused methods listed in your header. if you do, either remove them from the header, or create the method in your implementation.
- (void) dosomething
{
/* blank for now */
}
if you have -(void)dosomething in your implementation, define it in your header.
#import <Foundation/Foundation.h>
#interface KVCController : NSObject {
int fido;
}
#property(readwrite, assign) int fido;
- (void) dosomething;
#end