Code N°1:
NSMutableArray *arrayTmp = [[NSMutableArray alloc] initWithObjects:nil];
[arrayTmp addObject:@"line 1" ];
[arrayTmp addObject:@"line 2" ];
self.list = arrayTmp;
[self.tableView reloadData];
[super viewDidLoad];
[arrayTmp release];
Code N°2:
NSMutableArray *arrayTmp = [[NSMutableArray alloc] initWithObjects:nil];
NSString *fieldName = [[NSString alloc] init];
fieldName = [NSString stringWithFormat:@"%@",@"Ligne1"];
[arrayTmp addObject:(NSString *) fieldName];
[arrayTmp addObject:@"line 2" ];
self.list = arrayTmp;
[self.tableView reloadData];
[super viewDidLoad];
[arrayTmp release];
*Codes N°1 & N°2 do exactly the same job: they populate a tableview. My problem is with the code N°2:he displays the tableView but if I move the tableView with the finger, the iphone freeze. The Debugger shows the following message: "GDB:Program receive signal: "EXC_BAD_INSTRUCTION". I don't see what it is wrong. Has someone an idea of the problem ? Thank you in advance.*
-
My guess would be that
self.listdoes not retain the array, and when filling the table view you add references to the strings in that list. Your property should look like;@property (retain) NSArray* list;This is not a problem in the first example because the strings are literal - e.g. they are embedded in your program and are never deallocated.
The second example creates a temporary string, and although its reference is incremented when added to the array it will later deallocated and destroyed when the array is released.
Also this code;
NSString *fieldName = [[NSString alloc] init]; fieldName = [NSString stringWithFormat:@"%@",@"Ligne1"];Is going to result in a memory leak. You are allocating a new string, then changing the value in the pointer to be the result of the stringWithFormat call. If you wish fieldname to persist then the correct code would be;
NSString *fieldName = [[NSString stringWithFormat:@"%@",@"Ligne1"] retain]; -
Thank you for your very good advices. As you suggest, I retain the array in my @property:
@property (retain) NSArray *list;If in my code I put:
NSString *fieldName = [[[NSString alloc] initWithString: @"line 1"] retain]; [arrayTmp addObject:fieldName]; [arrayTmp addObject:@"line 2" ];it's working!
But if I put:
NSString *fieldName = [[[NSString alloc] initWithString: [NSString stringWithFormat: @"line 1"] ] retain]; [arrayTmp addObject:fieldName]; [arrayTmp addObject:@"line 2" ];it's display well the tableview but if I move the tableView 2 or 3 times with the finger, the iphone freeze.And unfortunately, I need to use stringWithFormat & stringWithUTF8String in order to populate my tableView from a database.
The error is still "EXC_BAD_ACCESS". But I don't know how to perform a backtrace. The Debugger shows:
0 0x300c8c18 in objc_msgSend
1 0x30b524dc in -[UILabel text]
2 0x30c07b44 in -[UITableViewCell layoutSubviews]
3 0x30a74020 in -[UIView(CALayerDelegate) _layoutSublayersOfLayer:]
4 0x31dd20f0 in -[CALayer layoutSublayers]
5 0x31dd2000 in CALayerLayoutIfNeeded
6 0x31dd1774 in CAContextCommitTransaction
7 0x31dd143c in CATransactionCommit
8 0x3026a0ec in __CFRunLoopDoObservers
9 0x30269920 in CFRunLoopRunSpecific
10 0x30269326 in CFRunLoopRunInMode
11 0x31563e60 in GSEventRunModal
12 0x30a4feb8 in -[UIApplication _run]
13 0x30a5961c in UIApplicationMain
14 0x000020bc in main at main.m:14
asm obj_msgSend 0x300c8cc04:1 0x300c8c04 <+0000> teq r0, #0 ; 0x0
0x300c8c08 <+0004> moveq r1, #0 ; 0x0
0x300c8c0c <+0008> bxeq lr
0x300c8c10 <+0012> stmdb sp!, {r3, r4, r5, r6}
0x300c8c14 <+0016> ldr r4, [r0]
0x300c8c18 <+0020> ldr r5, [r4, #8]
0x300c8c1c <+0024> ldr r6, [r5]
0x300c8c20 <+0028> add r3, r5, #8 ; 0x8
0x300c8c24 <+0032> and r5, r6, r1, lsr #2
0x300c8c28 <+0036> ldr r4, [r3, r5, lsl #2]
0x300c8c2c <+0040> teq r4, #0 ; 0x0
0x300c8c30 <+0044> add r5, r5, #1 ; 0x1
0x300c8c34 <+0048> beq 0x300c8c54
0x300c8c38 <+0052> ldr ip, [r4]
0x300c8c3c <+0056> teq r1, ip
0x300c8c40 <+0060> and r5, r5, r6
0x300c8c44 <+0064> bne 0x300c8c28
0x300c8c48 <+0068> ldr ip, [r4, #8]
0x300c8c4c <+0072> ldmia sp!, {r3, r4, r5, r6}
0x300c8c50 <+0076> bx ip
0x300c8c54 <+0080> ldmia sp!, {r3, r4, r5, r6}
0x300c8c58 <+0084> b 0x300c8c5c
-
Here's how you should use code 2
NSString *fieldName = [[NSString alloc] initWithString:@"Ligne1"]; NSMutableArray *arrayTmp = [NSMutableArray arrayWithObjects:fieldName, @"line2", nil]; //I would suggest using @"Ligne1" instead of fieldName if possible self.list = [arrayTmp retain]; //This will make sure even after releasing arrayTmp, list is not affected [self.tableView reloadData]; [arrayTmp release]; -
Thank you for your replies.
At the end, I resolve my problem by:
-adding a "retain" to my NNString fieldName
-removing a "release" on a variable in the tableView method "cellForRowAtIndexPath"
Thank again for your helpfull support !
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.