Is there a way for me to combine these 3 methods into just 1? - objective-c

Basically, I have 3 delegate methods that have almost the exact same code except for 1 line in each and the parameters. I realize that I can encapsulate a lot of the code to make 3 or 4 lines of code in each method, but I'm wondering if there's a way to create just 1 method.
Also, the methods being called on tempData have the same method name as the delegate methods below, but they are actually different methods.
- (void)addElement:(NSString *)currentElement FromKeyboard:(NSString *)name {
UIView *tempView;
NSMutableArray *tempViewList;
EquationData *tempData;
if ([name isEqualToString:#"leftEqCellKeyboard"]) {
tempData = leftData;
tempViewList = leftEqViewList;
tempView = equationCell.leftView;
}
if ([name isEqualToString:#"rightEqCellKeyboard"]) {
tempData = rightData;
tempViewList = rightEqViewList;
tempView = equationCell.rightView;
}
[tempData addElement:currentElement]; // different
if ([tempViewList count] != 0)
[self clearViewsStoredIn:tempViewList];
[self setUpView:tempView fromArray:tempData.equation toArray:tempViewList];
}
- (void)changeState:(NSString *)stateName FromKeyboard:(NSString *)name {
UIView *tempView;
NSMutableArray *tempViewList;
EquationData *tempData;
if ([name isEqualToString:#"leftEqCellKeyboard"]) {
tempData = leftData;
tempViewList = leftEqViewList;
tempView = equationCell.leftView;
}
if ([name isEqualToString:#"rightEqCellKeyboard"]) {
tempData = rightData;
tempViewList = rightEqViewList;
tempView = equationCell.rightView;
}
[tempData changeState:stateName]; // different
if ([tempViewList count] != 0)
[self clearViewsStoredIn:tempViewList];
[self setUpView:tempView fromArray:tempData.equation toArray:tempViewList];
}
- (void)changeCharge:(NSString *)chargeIncrease FromKeyboard:(NSString *)name {
UIView *tempView;
NSMutableArray *tempViewList;
EquationData *tempData;
if ([name isEqualToString:#"leftEqCellKeyboard"]) {
tempData = leftData;
tempViewList = leftEqViewList;
tempView = equationCell.leftView;
}
if ([name isEqualToString:#"rightEqCellKeyboard"]) {
tempData = rightData;
tempViewList = rightEqViewList;
tempView = equationCell.rightView;
}
[tempData changeCharge:chargeIncrease]; // different
if ([tempViewList count] != 0)
[self clearViewsStoredIn:tempViewList];
[self setUpView:tempView fromArray:tempData.equation toArray:tempViewList];
}

(Perhaps you should check out http://codereview.stackexchange.com)
The "different" part is always of the form [tempData doSomethingOn:aString];, so you can parametrize with the selector "doSomethingOn:":
-(void)doSomethingOnString:(NSString*)parameter
withSelector:(SEL)selector
fromKeyboard:(NSString*)name
{
// The common parts before
[tempData performSelector:selector withObject:parameter];
// The common parts after
}
-(void)addElement:(NSString *)currentElement FromKeyboard:(NSString *)name {
[self doSomethingOnString:currentElement
withSelector:#selector(addElement:)
fromKeyboard:name];
}
// etc.
See also:
-performSelector:withObject:
The "Selector" concept in Objective-C

Related

How do I find the minimum value of a binary tree?

I'm trying to find the minimum value of a binary tree. Every time I run my code I get a long 5 digit number like '32675'. I'm pretty sure my understanding of pointers is wrong, but I'm not positive. If I could get some advice I'd really appreciate it. Thanks!
Node definition
#interface Node:NSObject {
#property (nonatomic, strong) Node *left;
#property (nonatomic, strong) Node *right;
#property (nonatomic, assign) int *value;
}
-(id)initWithValue:(int)val {
self = [super init];
if(self) {
self.value = &(val);
self.left = nil;
self.right = nil;
}
return self;
}
Insert Algorithms for Tree
-(void)insertValue:(int)value {
Node *node = [[Node alloc] initWithValue:value];
[self insertNode:node];
}
-(void)insertNode:(Node *)node {
if (root == nil) {
root = node;
} else {
[node insertNode:node];
}
}
Insert Algorithms for Node
-(void)insertNode:(Node *)node{
if (node.value < self.value) {
[self insertOnLeft:node];
} else {
[self insertOnRight:node];
}
}
-(void)insertOnLeft:(Node *)node {
if (self.left == nil) {
self.left = node;
} else {
[self.left insertNode:node];
}
}
-(void)insertOnRight:(Node *)node {
if (self.right == nil) {
self.right = node;
} else {
[self.right insertNode:node];
}
}
3 values go in to my tree:
[tree insertValue:4];
[tree insertValue:6];
[tree insertValue:2];
int min = [tree findMinimum];
Tree's findMinimum method is called
-(int)findMinimum {
assert(root != nil);
return [root findMinimum];
}
Which call's root's findMinimum - root is a node
-(int)findMinimum {
Node *node = self;
int min = 0;
while (node != nil) {
min = *(node.value);
node = node.left;
}
return min;
}
Your are filling your tree not with integers but with stack addresses which are immediately invalid with this code:
self.value = &(val);
Here val is a parameter variable, which will disappear as soon as the method returns. Taking its address should only be done in rare circumstances and that address should never be stored in a location which outlives val.
Change the type of the value property of Node to int and remove the uses of address of (&) and indirection (*) associated with that property.
HTH
The assignment in the initializer of a pointer to the parameter won't work. Unless you have a good reason not to, actually allocate the int into the Node structure by declaring it an int, not an int *. So your initializer will look like this:
-(id)initWithValue:(int)val {
self = [super init];
if(self) {
self.value = val;
}
return self;
}
EDIT If you weren't sorting on insert (which I missed in the OP), you could instead search for the min recursively as follows:
-(int)findMinimum {
if (self.left && self.right)
return MIN([self.left findMinimum], [self.right findMinimum]);
else if (self.left)
return [self.left findMinimum];
else if (self.right)
return [self.right findMinimum];
else
return self.value;
}

How can I optimize this huge if/else if block within observeValueForKey

I have a controller that is registered as an observer for a LOT of properties on views. This is our -observeValueForKeyPath:::: method:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void*)context
{
if( context == kStrokeColorWellChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kStrokeColorProperty];
}
else if( context == kFillColorWellChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kFillColorProperty];
}
else if( context == kBodyStyleNumChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kBodyStyleNumProperty];
}
else if( context == kStyleChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kStyleProperty];
}
else if( context == kStepStyleChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kStepStyleProperty];
}
else if( context == kFirstHeadStyleChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kFirstHeadStyleProperty];
}
else if( context == kSecondHeadStyleChangedContext )
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:kSecondHeadStyleProperty];
}
And there's actually about 3x more of these else if statements.
One thing you can see is that each block has the same code, which makes me think that it's possible to optimize this.
My initial thought was to have an NSDictionary called keyPathForContextDictionary where the keys are the constants with the Context suffix (of type void*), and the values are the appropriate string constants, denoted by the Property suffix
Then this method would only need one line:
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:keyPathForContextDictionary[context]];
Note that I need to use a data structure of some sort to identify which keyPath to use, and I can't simply use the keyPath argument passed into the method. This is because there are multiple views that have the same property I'm observing (for example, color wells have the color property). So each view needs to determine a unique keypath, which is currently being determined based off of the context
The problem with this is that you cannot use void* as keys in an NSDictionary. So... does anybody have any recommendations for what I could do here?
EDIT:
Here's an example of how the constants are defined:
void * const kStrokeColorWellChangedContext = (void*)&kStrokeColorWellChangedContext;
void * const kFillColorWellChangedContext = (void*)&kFillColorWellChangedContext;
void * const kBodyStyleNumChangedContext = (void*)&kBodyStyleNumChangedContext;
void * const kStyleChangedContext = (void*)&kStyleChangedContext;
NSString *const kStrokeColorProperty = #"strokeColor";
NSString *const kFillColorProperty = #"fillColor";
NSString *const kShadowProperty = #"shadow";
NSString *const kBodyStyleNumProperty = #"bodyStyleNum";
NSString *const kStyleProperty = #"style";
The type void * is not so much a type unto itself that you have to match, as it is "generic pointer". It's used for the context argument precisely so that you can use any underlying type that you like, including an object type. All you have to do is perform the proper casts.
You can therefore change your kTHINGYChangedContexts to be NSStrings or any other object you like very easily, and then use them as keys in your context->key path mapping.
Start with:
NSString * const kStrokeColorWellChangedContext = #"StrokeColorWellChangedContext";
When you register for observation, you must perform a bridged cast:
[colorWell addObserver:self
forKeyPath:keyPath
options:options
context:(__bridge void *)kStrokeColorWellChangedContext];
Then when the observation occurs, you do the reverse cast:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void*)ctx
{
NSString * context = (__bridge NSString *)ctx;
// Use context, not ctx, from here on.
}
And proceed to your key path lookup from there.
Josh Caswell had a great answer, but I didn't want to modify the type of our constants into NSStrings*
So a solution instead, was to cast the void* into NSValues w/ -valueWithPointer. This way I could use the void* as keys in my dictionary
Here's the code:
NSString *toolKeyPath = [[ToolController keyPathFromContextDictionary] objectForKey:[NSValue valueWithPointer:context]];
if( toolKeyPath )
{
if( [change objectForKey:NSKeyValueChangeNewKey] == (id)[NSNull null] )
{
[self setValue:nil forKey:toolKeyPath];
}
else
{
[self setValue:[change objectForKey:NSKeyValueChangeNewKey] forKey:toolKeyPath];
}
}
And the dictionary:
+(NSDictionary*) keyPathFromContextDictionary
{
return #{
[NSValue valueWithPointer:kStrokeColorWellChangedContext] : kStrokeColorProperty,
[NSValue valueWithPointer:kFillColorWellChangedContext] : kFillColorProperty,
[NSValue valueWithPointer:kBodyStyleNumChangedContext] : kBodyStyleNumProperty,
[NSValue valueWithPointer:kStyleChangedContext] : kStyleProperty,
[NSValue valueWithPointer:kStepStyleChangedContext] : kStepStyleProperty,
[NSValue valueWithPointer:kFirstHeadStyleChangedContext] : kFirstHeadStyleProperty,
[NSValue valueWithPointer:kSecondHeadStyleChangedContext] : kSecondHeadStyleProperty,
[NSValue valueWithPointer:kShadowChangedContext] : kShadowProperty,
[NSValue valueWithPointer:kStrokeWidthChangedContext] : kStrokeWidthProperty,
[NSValue valueWithPointer:kBlurRadiusChangedContext] : kBlurRadiusProperty,
[NSValue valueWithPointer:kFontSizeChangedContext] : kFontSizeProperty
};
}

Populating ViewBased table from data in 6 different NSMutable arrays

I have 6 different NSMutable arrays [(Arr(A); Arr(B); etc.] each of which represents data for one cell of a row in the table. The array is essentially the key representation. They are built in a prior classes, passed to the current class and have exactly the same number of string objects (63) in each. The table is essential a data representation of
Questions:
Must I build a NSDictionary with 'keys' and 'objects'. How do I build thatDictionary. I have tried various methods stepping through a count loop with no success. I can to find a method for inserting objects for specific keys.
Can I load the table directly from the various arrays without a ViewController. I have the table and id's laid out but I have not been able to add a ViewController to this class - I only have 'Files Owner'. If this is easiest how can I do that.
If needed, how do I take elements of the 6 arrays in order as a comma delimited string in another array that becomes the input to a row of of the table and therefore parsed into the table.
No code to offer because all my attempts w/code have been unsuccessful.
NEED SOME SPECIFIC DIRECTION HERE.
.h
// ReportsOutput.h
// Stamp Collection
// Created by Terry Lengel on 4/20/15.
// Copyright (c) 2015 Terry Lengel. All rights reserved.
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#import "ReportsClass.h"
#interface ReportsOutput : NSWindowController <NSMenuDelegate,NSTableViewDataSource,NSTableViewDelegate,NSApplicationDelegate>{
// variable and outlet for the table
IBOutlet NSTableView *rptTable;
}
// data element sources
#property(nonatomic,strong) NSMutableArray *tblYrScott;
#property(nonatomic,strong) NSMutableArray *tblYrExt;
#property(nonatomic,strong) NSMutableArray *tblYrYear;
#property(nonatomic,strong) NSMutableArray *tblYrType;
#property(nonatomic,strong) NSMutableArray *tblYrPrice;
#property(nonatomic,strong) NSMutableArray *tblYrDescription;
// the Display data source array for the table
#property(strong) NSMutableArray *rptData;
#pragma mark - Method Declarations
-(BOOL)conditionData;
-(NSDictionary *)makeDictionaryRecord:(NSString*)scott withInfo:(NSString*)ext withInfo:(NSString*)year withInfo:(NSString*)type withInfo:(NSString*)price withInfo:(NSString*)Description;
#end
.m
// ReportsOutput.m
// Stamp Collection
// Created by Terry Lengel on 4/20/15.
// Copyright (c) 2015 Terry Lengel. All rights reserved.
#import "ReportsOutput.h"
#import "ReportsClass.h"
#interface ReportsOutput ()
#end
#implementation ReportsOutput
#synthesize tblYrScott;
#synthesize tblYrExt;
#synthesize tblYrType;
#synthesize tblYrPrice;
#synthesize tblYrYear;
#synthesize tblYrDescription;
#synthesize rptData;
-(id)initWithWindow:(NSWindow *)window{
self = [super initWithWindow:window];
if (self){
// initialize code here
}
return self;
}
-(void)windowDidLoad {
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
-(void)applicationDidFinishLaunching:(NSNotification *)notification{
//Insert code here to initialize your application
}
// Terminate the app by using the RED button:
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:
(NSApplication *)sender{
return YES;
}
-(void)awakeFromNib{
if (self.conditionData == YES){
[rptTable reloadData];
}
}
-(BOOL)windowShouldClose:(id)sender{
return YES;
}
-(void)performClose:(id)sender{
[self close];
}
#pragma mark - Table View Data Source
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{
return rptData.count;
}
-(NSView *) tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
NSTableCellView *scott = [tableView makeViewWithIdentifier:#"Scott" owner:self];
scott.textField.stringValue = [self.rptData objectAtIndex:row];
return scott;
}
// request for sorting
-(void) tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray *)oldDescriptors{
// table view received sort request
//sort the data, then reload the tableView data:
[rptData sortUsingDescriptors:[rptTable sortDescriptors]];
[rptTable reloadData];
}
-(BOOL)conditionData{
BOOL conditionData = NO;
NSString *rPrice;
NSString *rExt;
NSString *rYear;
NSString *rType;
NSString *rDescription;
for (int b=0; b<[tblYrScott count]; ++b){
//condition source data to remove any null appearences
rExt = [tblYrExt objectAtIndex:b];
if (rExt == (id)[NSNull null] || rExt.length == 0 ){
rExt = #"None";
}else if ([rExt isEqualToString:#" "]){
rExt = #"None";
}else
rExt = [tblYrExt objectAtIndex:b];
rYear = [tblYrYear objectAtIndex:b];
if (rYear == (id)[NSNull null] || rYear.length == 0 ){
rYear = #" ";
}else
rYear = [tblYrYear objectAtIndex:b];
rType = [tblYrType objectAtIndex:b];
if (rType == (id)[NSNull null] || rType.length == 0 ){
rType = #" ";
}else
rType = [tblYrType objectAtIndex:b];
rPrice = [tblYrPrice objectAtIndex:b];
if (rPrice == (id)[NSNull null] || rPrice.length == 0 ){
rPrice = #"n/r";
}else
rPrice = [tblYrPrice objectAtIndex:b];
rDescription = [tblYrDescription objectAtIndex:b];
if (rDescription == (id)[NSNull null] || rDescription.length == 0 ){
rDescription = #" ";
}else
rDescription = [tblYrDescription objectAtIndex:b];
NSDictionary *rptData = #{#"Scott":[tblYrScott objectAtIndex:b],#"Ext":rExt,#"Year":rYear,#"Type":rType,#"Price":rPrice,#"Description":rDescription};
}
//[rptTable reloadData];
return conditionData = YES;
}
-(NSDictionary*) makeDictionaryRecord:(NSString *)scott withInfo: (NSString *)ext withInfo: (NSString *)year withInfo: (NSString *)type withInfo: (NSString *)price withInfo: (NSString *)description{
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:scott,#"Scott",ext,#"Ext",year,#"Year",type,#"Type",price,#"Price",description,#"Description", nil];
return dict;
}
#end
Data Sample:
2015-04-25 12:20:49.251 StampsProjectDev[2981:591183] rptData = {
Description = "Lunar New Year - Horse";
Ext = None;
Price = "n/r";
Scott = 4846;
Type = C;
Year = 2014;
}
2015-04-25 12:20:49.252 StampsProjectDev[2981:591183] rptData = {
Description = "Jimi Hendrix";
Ext = None;
Price = "n/r";
Scott = 4880;
Type = C;
Year = 2014;
}
2015-04-25 12:20:49.252 StampsProjectDev[2981:591183] rptData = {
Description = "Charlton Heston";
Ext = None;
Price = "n/r";
Scott = 4892;
Type = C;
Year = 2014;
}
2015-04-25 12:20:49.252 StampsProjectDev[2981:591183] rptData = {
Description = "Janice Joplin";
Ext = None;
Price = "n/r";
Scott = 4916;
Type = C;
Year = 2014;
}
2015-04-25 12:20:49.252 StampsProjectDev[2981:591183] rptData = {
Description = "Ralph Ellison";
Ext = None;
Price = "n/r";
Scott = 4866;
Type = C;
Year = 2014;
}
Must I build a NSDictionary with 'keys' and 'objects'. How do I build thatDictionary. I have tried various methods stepping through a count loop with no success. I can to find a method for inserting objects for specific keys.
Not required, but advisable.
// assume six arrays are array0, array1, ...
// assume array0.count == array1.count == etc
for (int i=0; i<array0.count; ++i) {
NSDictionary *di = #{ #"ar0":array0[i], #"ar1":array1[i],... };
}
But a better idea is an NSObject subclass that you create that is meaningful to your users and has properties from corresponding elements from the arrays (call it MeaningfulObject)....
// in your datasource's interface definition
#property(strong) NSMutableArray *myArrayOfMeaningfulObjects;
self.myArrayOfMeaningfulObjects = [#[] mutableCopy];
// assume array0.count == array1.count == etc
for (int i=0; i<array0.count; ++i) {
MeaningfulObject *mi = [MeaningfulObject meaningfulObjectWithAttribute0:array0[i] attribute1:array1[i]... ];
[self.myArrayOfMeaningfulObjects addObject:mi];
}
Can I load the table directly from the various arrays without a ViewController. I have the table and id's laid out but I have not been able to add a ViewController to this class - I only have 'Files Owner'. If this is easiest how can I do that.
The table loads itself. Your job is to provide it with a datasource, which is an array of objects representing rows. Most people opt to make the view controller who's view contains the table act as the datasource, but the table's datasource can be any object. The two required parts of the NSTableViewDatasource protocol are (1) numberOfRowsInTableView: like this:
return self.myArrayOfMeaningfulObjects.count;
And (2) tableView:viewForTableColumn:row: like this:
MeaningfulObject *mrow = self.myArrayOfMeaningfulObjects[indexPath.row];
// configure a tableview cell using mrow's attributes
cell.textLabel.text = mrow.attribute0;
If needed, how do I take elements of the 6 arrays in order as a comma delimited string in another array that becomes the input to a row of of the table and therefore parsed into the table.
Don't understand this one, but hopefully a good answer is implicit in the foregoing
EDIT, Upon review of the code, it seems to me that you've nearly got it. The code has declared an array that will be the basis of the datasource, like this:
#property(strong) NSMutableArray *rptData;
Good, but a consequential mistake is made here:
NSDictionary *rptData = #{#"Scott":[tblYrScott objectAtIndex:b],#"Ext":rExt,#"Year":rYear,#"Type":rType,#"Price":rPrice,#"Description":rDescription};
That's a dictionary which looks as if it represents a single row in the table, named confusingly like the NSArray property. It looks as if the dictionary is built then abandoned on the iteration of the loop, overwritten by the object for the next row. To make this work, the objects representing the rows must be added to the datasource, like this:
// renamed rptData dictionary to rowDictionary
NSDictionary *rowDictionary = #{#"Scott":[tblYrScott objectAtIndex:b],#"Ext":rExt,#"Year":rYear,#"Type":rType,#"Price":rPrice,#"Description":rDescription};
[self.rptData addObject:rowDictionary];

Dynamic Accessibility Label for CALayer

How do I make a CALayer accessible? Specifically, I want the layer to be able to change its label on the fly, since it can change at any time. The official documentation's sample code does not really allow for this.
The following assumes that you have a superview whose layers are all of class AccessableLayer, but if you have a more complex layout this scheme can be modified to handle that.
In order to make a CALayer accessible, you need a parent view that implements the UIAccessibilityContainer methods. Here is one suggested way to do this.
First, have each layer own its UIAccessibilityElement
#interface AccessableLayer : CALayer
#property (nonatomic) UIAccessibilityElement *accessibilityElement;
#end
now in its implementation, you modify the element whenever it changes:
#implementation AccessableLayer
... self.accessibilityElement.accessibilityLabel = text;
#end
The AccessableLayer never creates the UIAccessibilityElement, because the constructor requires a UIAccessibilityContainer. So have the super view create and assign it:
#pragma mark - accessibility
// The container itself is not accessible, so return NO
- (BOOL)isAccessibilityElement
{
return NO;
}
// The following methods are implementations of UIAccessibilityContainer protocol methods.
- (NSInteger)accessibilityElementCount
{
return [self.layer.sublayers count];
}
- (id)accessibilityElementAtIndex:(NSInteger)index
{
AccessableLayer *panel = [self.layer.sublayers objectAtIndex:index];
UIAccessibilityElement *element = panel.accessibilityElement;
if (element == nil) {
element = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self];
element.accessibilityFrame = [self convertRect:panel.frame toView:[UIApplication sharedApplication].keyWindow];
element.accessibilityTraits = UIAccessibilityTraitButton;
element.accessibilityHint = #"some hint";
element.accessibilityLabel = #"some text";
panel.accessibilityElement = element;
}
return element;
}
- (NSInteger)indexOfAccessibilityElement:(id)element
{
int numElements = [self accessibilityElementCount];
for (int i = 0; i < numElements; i++) {
if (element == [self accessibilityElementAtIndex:i]) {
return i;
}
}
return NSNotFound;
}

Do [sprite stopActionByTag: kTag]; work differently for CCAction and CCSequence?

//prog 1
-(void)gameLogic:(ccTime)dt
{
id actionMove = [CCMoveTo actionWithDuration:1.0 position:ccp(windowSize.width/2-400, actualY)];
[actionMove setTag:6];
[self schedule:#selector(update:)];
[hitBullet runAction:actionMove];
}
-(void)update:(ccTime)dt
{
if ( (CGRectIntersectsRect(hitRect, playerRect)) )
{
[[[self getActionByTag:6] retain] autorelease];
[hitBullet stopActionByTag: 6];
}
}
//prog 2
-(void)gameLogic:(ccTime)dt
{
id actionMove = [CCMoveTo actionWithDuration:1.0 position:ccp(windowSize.width/2-400, actualY)];
id hitBulletAction = [CCSequence actionWithDuration:(intervalforEnemyshoot)];
id hitBulletSeq = [CCSequence actions: hitBulletAction, actionMove, nil];
[hitBulletSeq setTag:5];
[self schedule:#selector(update:)];
[hitBullet runAction:hitBulletSeq];
}
-(void)update:(ccTime)dt
{
if ( (CGRectIntersectsRect(hitRect, playerRect)) )
{
[[[self getActionByTag:5] retain] autorelease];
[hitBullet stopActionByTag: 5];
}
}
While prog1 is working prog2 is not working ? I think the both are same. But why the two stopActions are working differently in two prog1 and prog2 ? I mean the actions are stopped in prog1 but the actions are not stopping in prog2 ?
thank You.
Srikanth, what version of cocos2d are you using?
The answer to your question is no. All actions are treated the same.
The code responsible for removing the action is the following:
// -[CCActionManager removeActionByTag:target:]
-(void) removeActionByTag:(int) aTag target:(id)target
{
NSAssert( aTag != kActionTagInvalid, #"Invalid tag");
NSAssert( target != nil, #"Target should be ! nil");
tHashElement elementTmp;
elementTmp.target = target;
tHashElement *element = ccHashSetFind(targets, CC_HASH_INT(target), &elementTmp);
if( element ) {
NSUInteger limit = element->actions->num;
for( NSUInteger i = 0; i < limit; i++) {
CCAction *a = element->actions->arr[i];
if( a.tag == aTag && [a originalTarget]==target)
return [self removeActionAtIndex:i hashElement:element];
}
// CCLOG(#"cocos2d: removeActionByTag: Action not found!");
} else {
// CCLOG(#"cocos2d: removeActionByTag: Target not found!");
}
}
What I would recommend you do is turn on Cocos2d debugging, and un-comment those two CCLog lines. That should tell you if there's a problem in there.
If that doesn't tell you anything, it may be of interest to look into the CCSequence class. Perhaps, if the sequence is being removed, it doesn't remove the actions IN the sequence itself?
All actions are treated equal, but perhaps this Sequence action should be an exception to that.