I am testing the call back and block function.
I'm using the objective-c in iOS.
I write a call back method name is "dosomethingProcessWithCompletion".
dosomethingProcessWithCompletion do something , then it will get the NSMutableDictionary value, I will use the nsmutabledictionary value to check something and return the value yes or no.
If the value is yes(------- AAAAA-------), I need break the
for( NSInteger i = 0 ; i < myAry.count; i++ ).. for loop .
and return the yes using tryToCallBlockMethod method.
If the value is no, the for loop will run to last item and return the no using tryToCallBlockMethod method.
But I don't known how to write the call back return value .
have anyone can give some hand?
My code below:
My AppTool declare:
typedef BOOL(^DoMyProcessCompletion)(NSMutableDictionary *completeresult);
+ (void) dosomethingProcessWithCompletion:(NSURL*)theUrl andUserPsd:(NSString*)psd withCompletion:(DoMyProcessCompletion) completion{
.....
....
..
NSMutableDictionary *resultDic = [NSMutableDictionary dictionary];
if( something == YES ){
[resultDic setObject:[NSNumber numberWithBool:YES] forKey:#"resultDicKey"];
[resultDic setObject:myData forKey:#"myDataDicKey"];
}else{
[resultDic setObject:[NSNumber numberWithBool:NO] forKey:#"resultDicKey"];
[resultDic setObject:[NSNull null] forKey:#"myDataDicKey"];
}
completion(resultDic)
}
My use and implement function is below:
-(BOOL) tryToCallBlockMethod{
for( NSInteger i = 0 ; i < myAry.count; i++ ){
userPsd = myAry[i];
[AppTool dosomethingProcessWithCompletion:[NSURL URLWithString:theUrl] andUserPsd:userPsd withCompletion:^(NSMutableDictionary *completeResult) {
BOOL result = [[completeResult objectForKey:#"resultDicKey"] boolValue];
if( result == YES){
//------- AAAAA-------
//------- if result is YES, will break the for look , and tryToCallBlockMethod will return YES.
return YES;
}else{
//------- BBBBBBB-------
return NO;
}
}];
}
}
Thank you very much.
You need to return boolean as below while you have used the Block inside the fuction.
-(void) tryToCallBlockMethod:(void(^)(BOOL isResult))callback{
if( result == YES){
callback(YES)
return YES;
}else{
callback(NO)
}
}
Related
i have some api call which returns some values and store it into Array while receiving i may get repeated values from the server which i suppose not to append when its already in Array and insert new Values,
here my sample codes :
-(void)getIdValue:(NSString*)getIdVal {
getTagIdList = [[NSMutableArray alloc]init];
BOOL isTheObjectThere = [getTagIdList containsObject: getIdVal];
NSLog(isTheObjectThere ? #"Yes" : #"No");
if (isTheObjectThere == NO){
[getTagIdList addObject:getIdVal];
NSLog(#"getTagIdList -->%#",getTagIdList);
} if (isTheObjectThere == YES){
return;
}
}
I want all the new data should be Stored in getTagIdList but i am getting only one record is storing
You are initialising the array within the method which is wrong. You should not be initiating the array where you try to store data.(which will remove all the old data stored in previous calls)
NSInteger count=[ArrayData count];
for (int i=0; i<count; i++) {
NSString *StringValue= ArrayData[i];
BOOL contains = [getTagIdList containsObject: StringValue];
if (contains==YES) {
NSLog(#"fail");
}
else{
[getTagIdList addObject: StringValue];
}
}
Here "ArrayData" is a json responce. getTagIdList is saving the string values.Try it i think this one is work.
From jegadeesh answer i updated your code
getTagIdList = [[NSMutableArray alloc]init];
-(void)getIdValue:(NSString*)getIdVal {
BOOL isTheObjectThere = [getTagIdList containsObject: getIdVal];
NSLog(isTheObjectThere ? #"Yes" : #"No");
if (isTheObjectThere == NO){
[getTagIdList addObject:getIdVal];
NSLog(#"getTagIdList -->%#",getTagIdList);
} if (isTheObjectThere == YES){
return;
}
}
I am trying to do an if/else statement where it checks to see if an array is empty. It seems like the first condition is evaluated and not met, and so it moves to the else and executes. This is the output on the screen (iOS):
The name that you see is there because the else statement gets executed. However there are 3 other usernames with scores of 0 which aren't getting displayed. Here is the relevant conditional:
NSArray *keyArray = [yy allKeys];
for(NSString *keyd in keyArray) {
NSLog(#"yy objectforkey *********: %#", [[yy objectForKey:keyd] debugDescription]);
if(![yy objectForKey:keyd]){
NSMutableDictionary* entry = [NSMutableDictionary new];
NSLog(#"inside yy object for key count 0 *****####***##*#*#*#");
[tableData addObject:keyd];
[matchesForUser addObject:#"0"];
entry[#"username"] = keyd;
entry[#"matches"] = #"0";
[entries addObject:entry];
}
else {
NSMutableArray *locs = [[NSMutableArray alloc] initWithArray:[yy objectForKey:keyd]];
//NSString *outerouter;
//NSNumber *outeroutermatches = [NSNumber numberWithInt:0];
for(NSDictionary *outterar in locs) {
NSMutableDictionary* entry = [NSMutableDictionary new];
NSLog(#"%# outtererjar descriptiong ##(#(#(#(#(#(#(#(#(#((#", [outterar description]);
entry[#"username"] = keyd;
entry[#"matches"] = [outterar valueForKey:#"groupmatches"];
if([entries count] > 0) {
for(int counter = 0; counter < [entries count]; counter++) {
if([[[entries objectAtIndex:counter] valueForKey:#"matches"] intValue] < [[entry valueForKey:#"matches"] intValue]) {
NSLog(#"GETTING IN IFFFFFF ABOOOVVEEEEE ******8888888*********");
//NSMutableDictionary *stud = [[NSMutableDictionary alloc] initWithObjectsAndKeys:keyd, #"username", nil];
[matchesForUser addObject:[outterar objectForKey:#"groupmatches"]];
[tableData addObject:keyd];
NSLog(#"%# WHAT IS ENTRIES>>>!!!!??!?!?!", [[entries objectAtIndex:counter] valueForKey:#"username"]);
if([keyd isEqualToString:[[entries objectAtIndex:counter] valueForKey:#"username"]]) {
NSLog(#"GETTING IN IFFFFFF ******8888888*********");
[entries removeObjectAtIndex:counter];
[entries insertObject:entry atIndex:counter];
}
else {
[entries addObject:entry];
}
}
else {
[entries addObject:entry];
}
}
}
else {
[matchesForUser addObject:[outterar objectForKey:#"groupmatches"]];
[tableData addObject:keyd];
[entries addObject:entry];
}
}
}
}
_tableViewScore and tableData are both arrays which are used to populate the UIScrollView(s). The code inside the if statement should execute every time an empty object is found (they are arrays). The else runs, that is why you see the username with the score, but it seems like the if isn't getting executed when the array is null.
When I output the object I am checking for, an empty object looks like this:
yy objectforkey *********: <__NSArrayM 0x170454cd0>(
)
I just need to be able to identify when one of the objects is like that. Thanks!
The line
![yy objectForKey:keyd]
checks
does the key keyd not exist in the dictionary
which is of course always false because all keys returned by the property allKeys are guaranteed to exist and a value for an existing key cannot be nil by definition.
If you want to check if the array is empty you have to write
![[yy objectForKey:keyd] count]
PS: Consider to use more descriptive variable naming rather than yy
I asked a similar question to test an Array of Bool values here but now I have changed it so the values are now Integer values and I want to see if any of them are positive.
Example, I add 10 new objects in a loop like below, then at some point some may change and then I need to do a test. It may be that I do not use NSNumber, as long as I cna get an int out of it.
// I create an array like
NSMutableArray *MyArray = [[NSMutableArray alloc]init];
for (int count = 0; count < 10; count++)
{
[MyArray addObject:[NSNumber numberWithInt:0]];
}
// At some point I change a value or two
[MyArray replaceObjectAtIndex:3 withObject:[NSNumber numberWithInt:5]];
....
....
....
....
[MyArray replaceObjectAtIndex:3 withObject:[NSNumber numberWithInt:7]];
if([MyArray containsPositiveObject])
{
// Get the integer
int MyValue = [MyArray[4]integerValue];
}
EDIT
I have tried this and it works but wondered if there was a faster method.
if([self containsPositiveValue:selectedItems])
{
// Do my stuff
}
And then
-(bool)containsPositiveValue:(NSArray *)numberArray
{
bool result = NO;
for (NSNumber *obj in numberArray)
{
if([obj integerValue])
{
result = YES;
break;
}
}
return result;
}
Try this.
NSArray *array = #[ #(-1) , #(-3) , #(0) , #(-4) , #(2) , #(-1) ]; // zero is not positvie or negitive
NSArray *newArray = [array filteredArrayUsingPredicate: [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return ( [evaluatedObject isKindOfClass:[NSNumber class]] && ([evaluatedObject integerValue] > 0) );
return NO;
}]];
if (newArray.count)
{
NSLog(#"There are positive values");
}
else
{
NSLog(#"There are no positive values") ;
}
Surely the simplest way would be to go:
NSArray * array = #[#(-1), #(-5), #(-5)];
for (NSNumber * number in array) {
if (number.intValue > 0) {
NSLog(#"Positive Values");
// Add custom code here
break;
}
}
This will then check if at least one item in the array is greater than zero and custom code can then be implemented.
I suppose it depends if you want to perform something if there are no positive values and something different if there is?
You could always add something like this:
NSArray * array = #[#(-1), #(-5), #(-5)];
NSInteger largestValue = 0;
for (NSNumber * number in array) {
if (number.intValue > largestValue) {
largestValue = number.intValue;
}
if (largestValue > 0) {
break;
}
}
if (largestValue > 0) {
NSLog(#"Positive Value");
}
else {
NSLog(#"All Negative Values");
}
Anyway it gets more complicated the more complicated you want it to work but it should be incredibly simple
I have a piece of code that returns an object of type Card like so:
-(Card*) drawRandomCard {
if ([self.cards count]) {
unsigned index = arc4random() % self.cards.count;
Card *randomCard = self.cards[index];
[self.cards removeObjectAtIndex:index];
NSLog(#"%#", randomCard.description); **//returns a description and not null**
return randomCard;
} else {
NSLog(#"nil");
return nil;
}
}
This actually works fine when I use it in other functions, but there is a problem with this one below:
- (IBAction)addCards:(UIButton *)sender {
int numberOfCardsToAdd = EXTRA_CARDS_NUMBER;
if ([[self.collectionView visibleCells] count] == 0) {
numberOfCardsToAdd = self.startingCardCount;
}
for (int i = 0; i < numberOfCardsToAdd; i++) {
if (!self.game.deck.isEmpty){
Card *cardToAdd = [self.game.deck drawRandomCard];
NSLog(#"%#", cardToAdd.description); **// gives (null)**
if (cardToAdd) { **// this does not get called**
// do stuff with cardToAdd
}
}
}
[self.collectionView reloadData];
}
So for some reason it seems my drawRandomCard, when called with the method above, does not work. Does anyone know how to fix this?
Thanks very much!
Edit: my method for initializing the game object that has the deck property:
- (id) initWithNumberOfCards: (int) numberOfCards withDeck: (SetsPlayingDeck *) deck {
self = [self init];
self.score = 0;
_deck = deck;
_cards = [[NSMutableArray alloc] initWithCapacity:numberOfCards];
for (int i = 0; i < numberOfCards; i++) {
[_cards addObject: [_deck drawRandomCard]];
}
return self;
}
This method is called right at the start of the program.
Edit #2:
Here is the code that initializes the game object, along with a deck object that is its property:
- (SetsGame *) game {
if (!_game) {
SetsPlayingDeck *deck = [[SetsPlayingDeck alloc] init];
_game = [[SetsGame alloc] initWithCardCount:self.startingCardCount usingDeck:deck];
}
NSLog(#"%#", _game.deck.description); **// this returns null!!**
return _game;
}
As far as I can see, the issue should lie with the method initWithCardCount:usingDeck:, where you probably forgot to assign the deck argument to the deck property (or for some reason the assignment is not executed):
_game = [[SetsGame alloc] initWithCardCount:self.startingCardCount usingDeck:deck];
So, please review this or post that method definition.
Maybe the problem is that you're running out of cards. Inside your init method you have the following line inside a for-loop:
[_cards addObject: [_deck drawRandomCard]];
And inside your drawRandomCard method you have the following line:
[self.cards removeObjectAtIndex:index];
I'm assuming that _cards(1st line) and self.cards(2nd line) are different objects.
Probably, by the time you call Card *cardToAdd = [self.game.deck drawRandomCard]; inside your addCards: method you don't have any cards left.
Try to set a breakpoint and step in the for-loop and let me know,
Hope this helps!
for (int i = 0; i< [delarsInfoArray count] ; i++)
{
NSString *lattitudeValue;
NSString *longitudeValue;
if ([[delarsInfoArray objectAtIndex:i]count]>1) {
lattitudeValue = [[[delarsInfoArray objectAtIndex:i]valueForKey:#"LATITUDE"]objectAtIndex:1];
longitudeValue = [[[delarsInfoArray objectAtIndex:i]valueForKey:#"LONGITUDE"]objectAtIndex:0];
}
else
{
lattitudeValue = #"";
longitudeValue = #"";
}
CLLocationCoordinate2D pinLocation;
if(([lattitudeValue floatValue] != 0) && ([longitudeValue floatValue] != 0) ) {
mapRegion.center.latitude = [lattitudeValue floatValue];
mapRegion.center.longitude = [longitudeValue floatValue];
if(pinLocation.latitude !=0 && pinLocation.longitude !=0) {
myAnnotation1 = [[MyAnnotation alloc] init];
if ([[delarsInfoArray objectAtIndex:i] count] == 0) {
myAnnotation1.title = #"";
myAnnotation1.subtitle = #"";
}
else
{
// NSLog(#"====== delears array is===%#",delarsInfoArray);
NSLog(#"===== delears array count is %d",[delarsInfoArray count]);
if ([[[delarsInfoArray objectAtIndex:i]valueForKey:#"Address"]objectAtIndex:2] !=nil)
{
myAnnotation1.title = [[[delarsInfoArray objectAtIndex:i]valueForKey:#"Address"]objectAtIndex:2];
}
if ([[[delarsInfoArray objectAtIndex:i]valueForKey:#"City"]objectAtIndex:3]!= nil) {
myAnnotation1.subtitle = [[[delarsInfoArray objectAtIndex:i]valueForKey:#"City"]objectAtIndex:3];
}
NSLog(#"%#",[[[delarsInfoArray objectAtIndex:i]valueForKey:#"City"]objectAtIndex:3]);
}
[dealerMapView setRegion:mapRegion animated:YES];
[dealerMapView addAnnotation:myAnnotation1];
myAnnotation1.coordinate = mapRegion.center;
[myAnnotation1 release];
}
}
}
The above code is written in the viewWillAppear.After loading the map in to the view,when i clicked on the map.app gets crashed.How can solve this crash?
There are a lot of issues here, but the one that leaps out to the top of the list are the lines that read:
if ([[[delarsInfoArray objectAtIndex:i]valueForKey:#"Address"]objectAtIndex:2] !=nil)
...
and
if ([[[delarsInfoArray objectAtIndex:i]valueForKey:#"City"]objectAtIndex:3]!= nil) {
...
The problem is that objectAtIndex of a valueForKey of an array will never be nil. You can't store a nil in an array, so what valueForKey does, if it doesn't find a value, is it uses a NSNull object, [NSNull null]. That designates that there was no value found, but uses NSNull (which can be added to the array) instead of nil (which can't).
The problem is likely that there is some subsequent code (for example, the code that tries to figure out the size of the callout bubble) which tries to get the length of the string, but since you stored a NSNull, it's trying to call the length method and it's failing.
You could fix this a number of ways, such as:
if ([[[delarsInfoArray objectAtIndex:i]valueForKey:#"Address"]objectAtIndex:2] != [NSNull null])
...