Only first For loop called - iphone

I have two for loops that add subviews to the view. The first one adds all the subviews, but the second for loop is not even executed! Whats Up?
- (void)createBoxes
{
for (int i; i<5; i++) {
GameBox *box = [[GameBox alloc] initWithFrame:CGRectMake((i * 64) + 7, 50, 50, 50)];
[self.view addSubview:box];
}
for (int e; e<5; e++) {
GameBox *box1 = [[GameBox alloc] initWithFrame:CGRectMake((e * 64) + 7, 107, 50, 50)];
[self.view addSubview:box1];
}
}

Proper way would be to initialize variables :
int i = 0;
int e = 0;
Otherwise you never know which value you'll get.

Why are you not initialising your loop variables? These are not standard for loops at all.

Related

how to properly use GCD to do long process on back thread and UI process/update on maion thread

i am working on this piece of code as this blocks main thread reported by time profiler.
OrderModule *module = [OrderModule sharedModule];
for(Modifier *modifier in modifierLists)
{
int merge = [module getModifierMergeOption:modifier.mModifierId productId:product.mProductId];//long process database interaction
for(ModifierItem *mod_product in modifier.activeModifiers)
{
NSString *modifierProductName = mod_product.productName;
if (merge == 1) {
modifierProductName = [modifierProductName stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"%# - ",product.mProductName] withString:#""];
}
numberOfModifiers++;
UILabel *modifierNameLabel = [[UILabel alloc] init];
// [modifierNameLabel setBackgroundColor:[UIColor redColor]];
modifierNameLabel.lineBreakMode = UILineBreakModeWordWrap;
modifierNameLabel.numberOfLines = 0;
modifierNameLabel.lineBreakMode = NSLineBreakByWordWrapping;
modifierNameLabel.numberOfLines = 0;
[modifierNameLabel setFont:DEFAULT_FONT(DEFAULT_FONTSIZE_MODIFIERNAME)];
modifierNameLabel.textColor = [UIColor colorWithRed:125.0f/255.0f green:127.0f/255.0f blue:131.0f/255.0f alpha:1.0f];
// modifierNameLabel.frame = CGRectMake(x, y, 140, 35);
modifierNameLabel.frame = CGRectMake(x, y, 120, 35);
modifierNameLabel.text = modifierProductName;
[orderDetailRow addSubview:modifierNameLabel];
UILabel *modifierAmount = [[UILabel alloc] init];
[modifierAmount setFont:DEFAULT_FONT(DEFAULT_FONTSIZE_MODIFIERNAME)];
modifierAmount.textColor = [UIColor colorWithRed:125.0f/255.0f green:127.0f/255.0f blue:131.0f/255.0f alpha:1.0f];
// modifierAmount.frame = CGRectMake(CGRectGetMaxX(modifierNameLabel.frame)+30, y, 100, 35);
modifierAmount.frame = CGRectMake(CGRectGetMaxX(modifierNameLabel.frame)+6, y, 100, 35);
[orderDetailRow addSubview:modifierAmount];
// modifiersCount++;
amountPrice=amountPrice+([mod_product.mExtraCost floatValue]*count);
[modifierAmount setText:[Utils currencyWithSymbol:[NSString stringWithFormat:#"%.02f",(([mod_product.mExtraCost floatValue]*count)+ 0.00001)]]];//simple manipulation
if ([mod_product.mExtraCost floatValue]<=0) { //3.0 changes
[modifierAmount setHidden:YES];
}
y = y + 25;
}
numberOfModifiers++;
}
[self setUpActiveModifierWithX:x andy:y Row:orderDetailRow andModifierList:modifierLists andProduct:product];
i have tried with this way:
-(void)setUpModifierWithX:(float)x andy:(float)y Row:(OrderDetailRow *)orderDetailRow andModifierList:(NSMutableArray *)modifierLists andProduct:(Product *)product
{
OrderModule *module = [OrderModule sharedModule];
float __block Y = y;
for(Modifier *modifier in modifierLists)
{
int __block merge;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
merge= [module getModifierMergeOption:modifier.mModifierId productId:product.mProductId];
dispatch_async(dispatch_get_main_queue(), ^
{
for(ModifierItem *mod_product in modifier.activeModifiers)
{
NSString *modifierProductName = mod_product.productName;
if (merge == 1) {
modifierProductName = [modifierProductName stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"%# - ",product.mProductName] withString:#""];
}
numberOfModifiers++;
UILabel *modifierNameLabel = [[UILabel alloc] init];
// [modifierNameLabel setBackgroundColor:[UIColor redColor]];
modifierNameLabel.lineBreakMode = UILineBreakModeWordWrap;
modifierNameLabel.numberOfLines = 0;
modifierNameLabel.lineBreakMode = NSLineBreakByWordWrapping;
modifierNameLabel.numberOfLines = 0;
[modifierNameLabel setFont:DEFAULT_FONT(DEFAULT_FONTSIZE_MODIFIERNAME)];
modifierNameLabel.textColor = [UIColor colorWithRed:125.0f/255.0f green:127.0f/255.0f blue:131.0f/255.0f alpha:1.0f];
// modifierNameLabel.frame = CGRectMake(x, y, 140, 35);
modifierNameLabel.frame = CGRectMake(x, y, 120, 35);
modifierNameLabel.text = modifierProductName;
[orderDetailRow addSubview:modifierNameLabel];
UILabel *modifierAmount = [[UILabel alloc] init];
[modifierAmount setFont:DEFAULT_FONT(DEFAULT_FONTSIZE_MODIFIERNAME)];
modifierAmount.textColor = [UIColor colorWithRed:125.0f/255.0f green:127.0f/255.0f blue:131.0f/255.0f alpha:1.0f];
// modifierAmount.frame = CGRectMake(CGRectGetMaxX(modifierNameLabel.frame)+30, y, 100, 35);
modifierAmount.frame = CGRectMake(CGRectGetMaxX(modifierNameLabel.frame)+6, y, 100, 35);
[orderDetailRow addSubview:modifierAmount];
// modifiersCount++;
amountPrice=amountPrice+([mod_product.mExtraCost floatValue]*count);
[modifierAmount setText:[Utils currencyWithSymbol:[NSString stringWithFormat:#"%.02f",(([mod_product.mExtraCost floatValue]*count)+ 0.00001)]]];
if ([mod_product.mExtraCost floatValue]<=0) { //3.0 changes
[modifierAmount setHidden:YES];
}
Y = Y + 25;
}
numberOfModifiers++;
});
});
}
[self setUpActiveModifierWithX:x andy:y Row:orderDetailRow andModifierList:modifierLists andProduct:product];
}
but setUpActiveModifierWithX:x is called before the for loop ends execution, how do i call setUpActiveModifierWithX:x method after that for loop.
Thanks for any suggestion
I'd step back from what you are doing, and learn how to use a TableViewController or CollectionViewController.
You seem to be creating an awful lot of subviews, which is an expensive operation. Table views and collection views avoid this by reusing the same views over and over again, just displaying different values. Instead of expensive views you use much cheaper cells. You also automatically only handle things that are actually visible, so if you have thousand items, only the dozen on your screen will take CPU time.
The easiest fix is putting it after the last statement in the block executed on the main thread:
EDIT
This below won't work, and unfortunately, there is no "easy fix" without using a third partly library. I leave the answer here for demonstrating how things quickly get more complex with asynchronous problems.
-(void)setUpModifierWithX:(float)x andy:(float)y Row:(OrderDetailRow *)orderDetailRow andModifierList:(NSMutableArray *)modifierLists andProduct:(Product *)product
{
OrderModule *module = [OrderModule sharedModule];
float __block Y = y;
for(Modifier *modifier in modifierLists)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
int merge= [module getModifierMergeOption:modifier.mModifierId productId:product.mProductId];
dispatch_async(dispatch_get_main_queue(), ^
{
for(ModifierItem *mod_product in modifier.activeModifiers)
{
...
}
numberOfModifiers++;
[self setUpActiveModifierWithX:x andy:y Row:orderDetailRow andModifierList:modifierLists andProduct:product];
});
});
}
}
It turned out that this seemingly easy task isn't actually that easy. I couldn't find a solution that's easier than the following, without resorting to a third party library which makes such tasks much easier (I'll propose a solution using an utility library later).
So, here is an approach which uses a recursive block.
WARNING
Recursive blocks, are tricky - and I wouldn't recommend to use them unless you know why and how you apply this technique.
The code snippet shows the principal approach, but your original problem needs to be adjusted.
Your method
-(void)setUpModifierWithX:(float)x andy:(float)y Row:(OrderDetailRow *)orderDetailRow andModifierList:(NSMutableArray *)modifierLists andProduct:(Product *)product
becomes now an asynchronous method:
-(void) foo
{
NSArray* array = #[#"a", #"b", #"c"]; // your input array, e.g. "modifierLists"
NSMutableArray* marray = [array mutableCopy]; // we need a mutable array here
typedef void (^completion_t)(id result);
typedef void (^block_t)(NSMutableArray*, completion_t);
// setting up block variable suitable for using that block recursively:
__block __weak block_t weak_block;
block_t block;
weak_block = block = ^(NSMutableArray*array, completion_t completion) {
// Check the termination condition for the "loop"
if ([array count] == 0) {
if (completion) {
completion(#"Finished");
}
return;
}
id item = array[0];
[array removeObjectAtIndex:0];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// process "item" on a secondary thread (private queue):
int merge = [item characterAtIndex:0]; //[module getModifierMergeOption:modifier.mModifierId productId:product.mProductId];
dispatch_async(dispatch_get_main_queue(), ^{
// On the main thread, setup the UIKit objects:
NSLog(#"%d", merge);
/*
for(ModifierItem *mod_product in modifier.activeModifiers)
{
...
}
numberOfModifiers++;
*/
// Continue the loop:
weak_block(array, completion); //looks scary!
});
});
};
// Start the loop:
block(marray, ^(id result){
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"result: %#", result);
//[self setUpActiveModifierWithX:x andy:y Row:orderDetailRow andModifierList:modifierLists andProduct:product];
});
});
}
Regarding recursive blocks, see this question ARC behavior within a recursive block and this answer on SO: https://stackoverflow.com/a/19626441/465677

How Do i create UIimageView Dynamically (XCODE)

Hi everybody I making an Xcode App but have now been stuck for 2 days
in my app I have to create some images (which balls) in the amount stated by the user .
e,g if the user says make 10 10 balls should appear on the same screen at random locations I know to make location random but can't figure how to do it ... how do i connect to the interface builder ???
tried this
1.h
UIImageView *c[100];
1.m
for (int i = 0; i < "users value" ; i++) {
float x = (float)(67 + ((95 + 22) * i));
UIImageView *c[i] = [[UIImageView alloc]
initWithFrame:CGRectMake(x, 20.0f, 95.0f, 149.0f)];
[ballsView[i]setImage:[UIImage imageNamed:#"1.png"]];
ballsView[i].opaque = YES;
ballsView[i].hidden = NO; /* change to YES for distribution */
}
use this. hope helps
for (int i = 0; i < "users value" ; i++)
{
float x = (float)(67 + ((95 + 22) * i));
UIImageView *c[i] = [[UIImageView alloc]
initWithFrame:CGRectMake(x, 20.0f, 95.0f, 149.0f)];
c[i].image=[UIImage imageNamed:#"1.png"]];
[ballsView[i] addSubView:c[i]];
ballsView[i].opaque = YES;
ballsView[i].hidden = NO; /* change to YES for distribution */
}

Set Buttons' Background randomly from array of images

else if (setIndexPath == 4)
{
viewWithButtons.frame = CGRectMake(5, 40, 310, 390);
int ch = 6;
int cv = 6;
for ( int i = 0 ; i < cv ; ++i )
{
for ( j = 0 ; j < ch ; ++j )
{
btnMatrix = [[[UIButton alloc] initWithFrame:CGRectMake(10+pw*j, 51+ph*i, width, height)] autorelease];
btnMatrix.tag = i*ch+j;
btnMatrix.userInteractionEnabled = TRUE;
[btnMatrix addTarget:self action:#selector(changeImage:) forControlEvents:UIControlEventTouchDown];
[btnMatrix setBackgroundImage:imgDefaultBG forState:UIControlStateNormal];
[viewWithButtons addSubview:btnMatrix];
[arrButton addObject:btnMatrix];
}
}
}
[self.view addSubview:viewWithButtons];
I am generating buttons dynamically according to the selected matrix, like 4 * 4, 4 * 5, 4 * 6, 5 * 6, 6 * 6 etc....
Buttons are completely set as per the selected matrix from above (the code is for 6 * 6 matrix).
Now i have to set random background images of these buttons.
I am not able to set this kind of dynamic buttons' background.
is there any effective way to set backgrounds dynamically in random order for each separate buttons?
for (intimg = 1; intimg <= 15; intimg++)
{
arr_FirstSet = [[NSMutableArray alloc] initWithObjects:[NSString stringWithFormat:#"%d_f_2.png",intimg], nil];
}
for (intimgSET2 = 1; intimgSET2 <= 15; intimgSET2++) {
arr_SecondSet = [[NSMutableArray alloc] initWithObjects:[NSString stringWithFormat:#"%d_s_2.png",intimgSET2], nil];
}
I am adding images in this format to the NSMutableArray.
How to pick random image from the above used arrays. I have to match both arrays images & give the result on buttons. If both matches, suppose i press on one button it will display 1_f_2.png & on another button press it will display 1_s_2.png (as background)then both of these buttons will be removed from the view.
I had tried many logics to get this.
I am not getting exactly what i am interested to do on touchdown of button.
Please suggest any code snippet or link or code also.
Thanks in advance.
- (UIImage*)randomImage {
NSInteger imageCount = [[self imageArray] count]
return [[self imageArray] objectAtIndex:arc4random() % imageCount];
}
If you want matching pairs. Use dictionary with two images, or simple class holding two images.

iPhone:How can I shuffle buttons in view

I have many no. of buttons on my view and I want to shuffle the buttons(change in position) then how can I shuffle the button in my view.
use arc4random()
and change position of your buttons
In your .h file : UIButton *buttonsarray[10];
In your .m file :
// Make array of button using following way.I used this method to creates button and you can use yours.
- (void)viewDidLoad {
[super viewDidLoad];
float y = 5;
int x = 0;
int count = 0;
for (int i = 0 ; i < 10; i++)
{
count ++;
buttonsarray[i] = [UIButton buttonWithType:UIButtonTypeRoundedRect];
buttonsarray[i].frame = CGRectMake(x, y, 100, 100);
[buttonsarray[i] setTitle:[NSString stringWithFormat:#"%d",i+1] forState:UIControlStateNormal];
x = x + 105;
[self.view addSubview:b[i]];
if(count == 3)
{
count = 0;
x = 0;
y = y+ 105;
}
}
}
// This function will soufflé your buttons
- (IBAction)btnClicked:(id)sender
{
int n = 10;
int swaper;
for (int i = 0 ; i < 10 ; i++)
{
int r = arc4random()%n;
if(r != swaper){
swaper = r;
CGRect r1 = buttonsarray[i].frame;
buttonsarray[i].frame = buttonsarray[swaper].frame;
buttonsarray[swaper].frame = r1;
n--;
}
}
}
Hope,this will help you..
You can do this
Make an Array with a group of CGPoints you will need to store the points as strings.
In the layoutSubViews method set something like this:
-(void)layoutSubViews{
[self.subviews enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) {
CGPoint newPoint = CGPointFromString([positionsArray objectAtIndex:idx]);
object.frame = CGRectMake(newPoint.x,newPoint.y,object.frame.size.width,object.frame.size.height);
}];
}
Then you will need to shuffle the positions in the positions array, you can see an example method here :How to Shuffle an Array
Now every time you need to Shuffle the positions you can call -(void)setNeedsLayout on your view.
There are more options but that was the first I thought of.
Good Luck

EXC_BAD_ACCESS when removeAllObject

I have a class named UICustomLabel with a variable NSMutableString : _text . I created a lot of this objects to display the content as page. Here is code to create :
for (int i = 0; i < linesOfFirstPage; i++) //first page is the special case
{
UICustomLabel * _centerLabel =[[UICustomLabel alloc] initWithFrame:CGRectMake(100.0, 555 + 35 * i, 575.0, 35.0)];//create label in follow kPortraitIpadfirstLabelRect area
if (!_isSmallFont) _centerLabel.frame = CGRectMake(100, 505 + 45 * i, 575, 45);
_centerLabel._textColor=kLabelTextColor;
_centerLabel._backgroundColor=kBackgroundColor;
_centerLabel._font=[UIFont systemFontOfSize:isSmallFont?25:32];
[_contentOfPage addObject:_centerLabel];
[self addSubview:_centerLabel];
[_centerLabel release];
}
After that when i want to remove all Label in my page :
if (_contentOfPage)
{
for (int i = 0; i < [_contentOfPage count]; i++)
{
UICustomLabel * tmp = [_contentOfPage objectAtIndex:i];
[tmp removeFromSuperview];
}
[_contentOfPage removeAllObjects];
}
But i get an error EXC_BAD_ACCESS when command [_contentOfPage removeAllObjects] excuted; When i reject the command [_text release] in the method dealloc of UICustomLabel, the program running fine. So what was the reason?