Inside of a class that subclasses CCNode, I have scheduled an -update:(ccTime)dt method. I also have a bunch of behavior objects that don't subclass CCNode, but also have an -update:(ccTime)dt method. Here's the inside of my CCNode's update method:
-(void)update:(ccTime)dt{
for(Behavior *currentBehavior in behaviors){
[currentBehavior update:dt];
}
}
When I NSLog the dt value passed into my CCNode's update, it prints out normal values (0.116699, 0.162726). However, when I NSLog the dt value from inside the behaviors' update methods, the printed numbers are all of a sudden really screwed up (0.000, 36893488147419103232, -2.000). It's the strangest thing. When I debug it, I'll see that the first dt value is normal, and then I'll step inside the behavior's update, and the value will suddenly change to something crazy. What's going on?
I figured it out. I didn't have -update:(ccTime)dt in my behavior class's .m file, and my theory is that it took the complier extra time to look for the method selector, which therefore screwed up the ccTime.
Related
I am bridging an objective-c library to React. In order to return the data I need, I have to use a callback. The only problem is, the native method that kicks off the process that generates the data (which is the method that I call from my React js file), is NOT the method that returns the data. In fact, there are quite a few methods between the one that I call, and the final result.
So I have a few options. Either completely rewrite the entire objective-c program (f*ck that), pass the callback function as an argument to every single method and ultimately to the final method where it will be used (this 'works' but is ugly), or a third option which this post is about.
I am new to objective-c (very new) so go easy on me.
Instead of passing the callback function around to every single method, I want to try and make it 'global'. My attempt at doing this looks like
#property(nonatomic,copy)RCTResponseSenderBlock globalCallback;
and the method where it is 'initialized' (which is also the method I call from js)
RCT_EXPORT_METHOD(startScan:(RCTResponseSenderBlock)callback) {
self.globalCallback = callback;
...
}
Now just to test that this works, I added a line of code immediately below the line where I 'initialized' my globalCallback:
RCT_EXPORT_METHOD(startScan:(RCTResponseSenderBlock)callback) {
self.globalCallback = callback;
self.globalCallback(#[[NSNull null], #"Test string"]);
...
}
And it works (as far as I can tell). The callback returns "Test String" to React, and I am able to see it. So I went over to the method where I actually want to return information from and added the same line of code to it (obviously removing the one from the above example):
-(void)theMethodIWantToReturnFrom {
self.globalCallback(#[[NSNull null], #"Test string"]);
...
}
However, this time it does not work. I get EXC_BAD_ACCESS. From what I understand, this may mean that my globalCallback has been deallocated. But whatever it means, I have not been able to figure out a solution yet. Any ideas / explainations regarding this error?
My NSMutableArray lOfSegments, declared as IVAR, get populated correctly. During the debug it shows 4 object in the array.
for (int x=0; [arrayOfSegmentsTcIn count]>x; x++) {
NSDictionary *segmentDic=[[NSDictionary alloc] initWithObjectsAndKeys: [arrayOfSegmentsNumbers objectAtIndex:x],#"segment",[arrayOfSegmentsTcIn objectAtIndex:x],#"tc_in",[arrayOfSegmentsTcOut objectAtIndex:x],#"tc_out", nil];
[lOfSegments addObject:segmentDic];
[myDMXML.segments addObject:segmentDic];
}
[self.xmlTCLable setStringValue:[myDMXML startTimeCode]];
[self.xmlDurationLable setStringValue:[myDMXML duration]];
[self xmlValidationCheck];
NSLog(#"arrayController:%#",[lOfSegments valueForKey:#"segment"]);
[self.tableViewOutlet reloadData];
NSLog list the array correctly but when reloadData is executed the code jumps to
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [lOfSegments count];
}
The array is null.
The Object is initialised in viewDidLoad as
lOfSegments = [[NSMutableArray alloc]init];
Please Help!
First, I recommend making your code more clear here by using self.lOfSegments rather than directly accessing an ivar. (The fact that the ivar lacks a leading _ is very suspicious as well, and raises the question of whether this is even the variable you think it is.)
On the assumption that this is the variable you think it is, and that you have overridden the standard behavior to make the ivar match the property or created explicit ivars (neither of which you should do), there are several common causes for this kind of problem:
The most likely cause is that you called your initialization code prior to viewDidLoad and then viewDidLoad blew away the array. Many things can run prior to viewDidLoad, and viewDidLoad can run more than once (at least this used to be true; I'd have to study whether the view-loading changes in iOS 6 made it guaranteed to be run once.)
You have some other way reset lOfSegments between the time your initialization code ran and the time reloadData ran. If you would reliably use self. then you could override setLOfSegments: so you could log this. Or you could mark this property readonly so you could prevent it. Thats one of many reasons that you should use properties, not ivars.
The setting code failed to run before reloadData. Ensure that the log statement actually printed prior to getting to reloadData and is on the same queue (the queue identifier will be part of the NSLog output in brackets). I don't think this is likely given your description, but it is a common problem.
There are two instances of this object. Make sure that the object that ran your initialization code is the same object that ran reloadData. This is a more common mistake then you may think. Log self and make sure the memory address is the same in both cases.
looks like you have variable with same name lOfSegments in method viewDidLoad. So in viewDidLoad you use stack variable, in numberOfRowsInTableView - instance variable.
Or maybe tableViewOutlete.dataSource pointing on different viewController
I am trying to use the completion handler on invoke to perform certain actions once the hub has return a result. Im using the following line currently:
myHub invoke:#"stpm" withArgs:messageParam completionHandler:^(SRHubResult *hubResult) {
NSLog(#"Complete");
}
But the block is never called. The invoke still works fine but the block never gets used. Any suggestions as to why?
I can only spot 1.5 issues with your snippet, completionHandler returns either NSDictionary, NSArray, NSNumber, or NSString. Also, is messageParam array?
I have found the issue. In SRHubProxy.m when the method send is called from SRHubProxy.m in invoke, the line:
[_connection send:hubData];
is wrong. The block never gets passed whether you have declared one or not. I changed it to:
[_connection send:hubData completionHandler:block];
which now passes the block correctly and it seems to work.
I have a type of object in my game that simply moves horizontally.. It has a method like this:
-(void)moveLeftWithBlock:(void(^)())block {
self.targetX = self.position.x - MOVE_AMOUNT;
id action = [CCMoveTo actionWithDuration:0.125f position:ccp(self.targetX, self.targetY)];
id ease = [CCEaseInOut actionWithAction:action rate:4];
[self runAction: [CCSequence actions: ease,
[CCCallBlock actionWithBlock:block], nil]];
}
...
Now, I wanted to make a second type of object that's exactly the same, except that it can also move vertically... My initial thought was to just subclass that object's class, and overwrite the moveLeftWithBlock and update its targetY.. but not only do I not like that solution because I still end up with 99% duplicate code amongst the two classes, but also because my game needs the Y position set prior to that moveLeftWithBlock method being called.
So next I thought-- Ok, so I can make my game call a prepareToMove method, which could do any kind of setup that might be required... For the main object type, nothing.. For this 2nd object type, set the targetY.
However, I immediately started thinking-- wait---- I know protocols are about explicitly defining methods that are OPTIONAL or REQUIRED, and it made me think that perhaps I should be utilizing this here, but I just am not sure how.
So, can anyone explain to me how a protocol could be used in this case-- and if it is "the way to go" or not?
Any of these would work. You could add to this andAlsoMoveVertically: (bool) isVertical and then add the vertical movement in an if statement in the function.
I've set up two views: ViewControllerOne and ViewControllerTwo.
In my ViewControllerTwo, I have a numeric variable (dataValue) that I input in a text field that I later use as a float value in a calculation.
The user can move to another Class view (ViewControllerOne), but when they return to ViewControllerTwo, the variable they inputted in the text field is not retained and returns to the default value I define in my ViewControllerTwo.m file.
How can I get my ViewControllerTwo to remember my dataValue?
I've #synthesized my dataValueTextField and defined my default dataValue in ViewControllerTwo.m:
#synthesize dataValueTextField;
float dataValue = 1.00;
Then, later, I've converted my dataValueTextField into a float value:
float textFieldData = [dataValueTextField.text floatValue];
dataValue = textFieldData;
But it never remembers dataValue when I switch views back and forth. Do I need to add something to my viewWillDisappear or do I need to add something to my viewWillDisappear or ViewWillAppear methods?
Any help would be appreciated. I've been grasping at straws trying different things to no avail.
Thanks.
Is it possible that when you're switching views, its actually creating a new instance of the view controller each time? That might explain the value resetting back to its default. Another possibility is that you have code setting it to the default value being called from an event callback which is triggered whenever the view shows up. You could try logging out all the event handlers and see whats getting called when switching between views.
If you are getting a memory warning, the View may be getting unloaded and then reloaded when you return to it causing viewDidLoad to be called again. This would cause your value in the UITextField to be reset.
dataValue is a float, which means it is a primitive. primitives are not retained and are lost at the end of each method. it looks by how you declare dataValue, it is a singleton? i'm not 100% on how singleton's are handled when you switch view, if they are released or are retained.
maybe best to make dataValue into a instance variable? like you did with dataValueTextField.