1

代码 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];

代码 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];

代码 N°1 和 N°2 执行完全相同的工作:它们填充一个表格视图。我的问题是代码 N°2:他显示 tableView 但如果我用手指移动 tableView,iphone 就会冻结。调试器显示以下消息:“GDB:程序接收信号:“EXC_BAD_INSTRUCTION”。我看不出它出了什么问题。有人知道这个问题吗?提前谢谢你。

4

5 回答 5

2

我的猜测是self.list不保留数组,并且在填充表格视图时添加对该列表中字符串的引用。你的财产应该是这样的;

@property (retain) NSArray* list;

这在第一个示例中不是问题,因为字符串是字面的 - 例如,它们嵌入在您的程序中并且永远不会被释放。

第二个示例创建了一个临时字符串,尽管它的引用在添加到数组时会增加,但稍后会在释放数组时释放并销毁。

还有这个代码;

NSString *fieldName = [[NSString alloc] init];
fieldName = [NSString stringWithFormat:@"%@",@"Ligne1"];

将导致内存泄漏。您正在分配一个新字符串,然后将指针中的值更改为 stringWithFormat 调用的结果。如果您希望 fieldname 持续存在,那么正确的代码将是;

NSString *fieldName = [[NSString stringWithFormat:@"%@",@"Ligne1"] retain];
于 2009-03-24T22:01:27.473 回答
0
self.list=[NSArray arrayWithArray:arrayTmp];

只需分配 self.list 。这是在创造糟糕的执行官。因为您没有为列表分配内存。

保留并不能解决问题

于 2012-06-14T10:23:34.927 回答
0

谢谢您的回复。

最后,我通过以下方式解决了我的问题:

- 在我的 NNString 字段名中添加“保留”

- 删除 tableView 方法“cellForRowAtIndexPath”中变量的“释放”

再次感谢您的帮助支持!

于 2009-03-26T18:16:10.090 回答
0

谢谢你非常好的建议。正如您所建议的,我将数组保留在我的@property 中:

  @property (retain) NSArray *list;

如果在我的代码中我输入:

 NSString *fieldName = [[[NSString alloc] initWithString: @"line 1"] retain];
[arrayTmp addObject:fieldName];
[arrayTmp addObject:@"line 2" ];

它正在工作!

但如果我说:

NSString *fieldName = [[[NSString alloc] initWithString: [NSString stringWithFormat: @"line 1"] ] retain];
[arrayTmp addObject:fieldName];
[arrayTmp addObject:@"line 2" ];

它可以很好地显示 tableview,但是如果我用手指移动 tableView 2 或 3 次,iphone 就会冻结。不幸的是,我需要使用 stringWithFormat 和 stringWithUTF8String 才能从数据库中填充我的 tableView。

错误仍然是“EXC_BAD_ACCESS”。但我不知道如何执行回溯。调试器显示:

0 0x300c8c18 在 objc_msgSend

1 0x30b524dc 在 -[UILabel 文本]

2 0x30c07b44 在-[UITableViewCell layoutSubviews]

3 0x30a74020 在-[UIView(CALayerDelegate)_layoutSublayersOfLayer:]

4 0x31dd20f0 在 -[CALayer layoutSublayers]

5 0x31dd2000 在 CALayerLayoutIfNeeded

6 CAContextCommitTransaction 中的 0x31dd1774

7 0x31dd143c 在 CATransactionCommit

8 0x3026a0ec 在 __CFRunLoopDoObservers

9 CFRunLoopRunSpecific 中的 0x30269920

10 0x30269326 在 CFRunLoopRunInMode

11 0x31563e60 在 GSEventRunModal

12 0x30a4feb8 在 -[UIApplication_run]

13 0x30a5961c 在 UIApplicationMain

14 0x000020bc 在 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> 添加 r3, r5, #8 ; 0x8

0x300c8c24 <+0032> 和 r5, r6, r1, lsr #2

0x300c8c28 <+0036> ldr r4, [r3, r5, lsl #2]

0x300c8c2c <+0040> teq r4, #0 ; 0x0

0x300c8c30 <+0044> 添加 r5, r5, #1 ; 0x1

0x300c8c34 <+0048> beq 0x300c8c54

0x300c8c38 <+0052> ldr ip, [r4]

0x300c8c3c <+0056> teq r1, ip

0x300c8c40 <+0060> 和 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

于 2009-03-25T13:27:08.060 回答
0

以下是您应该如何使用代码 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];
于 2009-03-26T14:30:02.877 回答