NSArray的赋值抛出异常:EXC_BAD_ACCESS(即使关闭ARC也是如此)

时间:2014-01-06 18:59:52

标签: ios objective-c nsarray automatic-ref-counting

我是Objective-C的新手。我想做的是建立一个Twitter客户端。以下代码总是在行self.timeline = [[NSArray alloc] initWithArray:newTimeline];处抛出错误,我不知道它为什么会发生。

这是界面:

            #import <UIKit/UIKit.h>

            @interface TweetList : NSObject<UITableViewDataSource> {
                NSArray* timeline;
            }

            @property (nonatomic, retain) NSArray* timeline;
            - (void) setCurrentTimeline:(NSArray*) newTimeline;

            @end

这是实施:

            #import "TweetList.h"

            @implementation TweetList

            @synthesize timeline;

            #define TWEET_LABEL_TAG 1

            - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
                return timeline.count;
            }

            - (UITableViewCell*) tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath {
                static NSString* cellIdentifier = @"TweetContainerCell";
                UILabel* tweetLabel;
                UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
                if(cell == nil) {
                    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
                    tweetLabel = [[UILabel alloc] initWithFrame:cell.frame];
                    tweetLabel.tag = TWEET_LABEL_TAG;
                    tweetLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
                    [cell.contentView addSubview:tweetLabel];
                }
                else
                    tweetLabel = (UILabel*)[cell.contentView viewWithTag:TWEET_LABEL_TAG];
                NSDictionary* tweet = [self.timeline objectAtIndex:indexPath.row];
                tweetLabel.text = [tweet objectForKey:@"text"];
                return cell;
            }

            - (id) init {
                self = [super init];
                if(self != nil)
                    self.timeline = [[NSArray alloc] init];
                return self;
            }

            - (void) dealloc {
                self.timeline = nil;
            }

            - (void) setCurrentTimeline:(NSArray*) newTimeline {
                @try {
                    self.timeline = [[NSArray alloc] initWithArray:newTimeline];
                }
                @catch (NSException *exception) {
                    NSLog(@"Exception: %@", exception);
                }
            }

            @end

我稍微研究过这个问题。我找到的解决方案之一是关闭ARC。我试过了,但结果还是一样的。任何帮助将不胜感激。

编辑:

这是调用setCurrentTimeline的代码:

                NSError* jsonError;
                self.timeline = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&jsonError];
                if(jsonError == nil) {
                    self.output = [[NSString alloc] init];
                    TweetList* tweetList = [[TweetList alloc] init];
                    [tweetList setCurrentTimeline:self.timeline];
                    UIView* wrapperView = [[UIView alloc] initWithFrame:self.view.frame];
                    [self.view addSubview:wrapperView];
                    [wrapperView setBounds:CGRectMake(0, 200, self.view.frame.size.width, self.view.frame.size.height)];
                    UITableView* tableView = [[UITableView alloc] initWithFrame:wrapperView.frame];
                    tableView.dataSource = tweetList;
                    [wrapperView addSubview:tableView];
                }
                else
                    self.output = [jsonError localizedDescription];

1 个答案:

答案 0 :(得分:-1)

编辑:我根据评论中的讨论重写了这个答案。

您正在将时间轴数组作为类标题中的属性进行访问。 因此,您无需为阵列实现自定义setter。因此,您可以完全删除setCurrentTimeline方法。 将界面更改为:

 #import <UIKit/UIKit.h>

 @interface TweetList : NSObject<UITableViewDataSource>{
     NSArray* timeline;
 }

 @property (nonatomic, strong) NSArray* timeline;  //assumes ARC

 @end

然后,当您需要设置新的时间轴数组时,可以使用点表示法设置它而不是调用旧的setCurrentTimeline方法:

tweetlist.timeline = self.timeline;