我在编程方面很新,我目前正在研究我遇到一些问题的块。我很难到达在我的块中定义的对象。实际上我无法准确地解释这个问题,所以我给你一些代码和图片,并希望它是有道理的,并且你原谅我的狡猾的知识并试图帮助我理解这个问题。
所以我从运行这个块开始
- (void)fetchSite
{
//Initiate the request...
[[FeedStore sharedStore] fetchSites:^(RSSChannel *objSite, NSError *err) {
//When the request completes, this block will be called
if (!err) {
//If everything went ok, grab the object
channelSite = objSite;
//Now we need to extract the first siteId and give it to sharedstore
RSSItem *site = [[channelSite sites] objectAtIndex:0];
NSString *currentSiteId = [NSString stringWithFormat:@"%@", [site siteNumber]];
NSLog(@"DEBUG: LVC: fetchSite: currentSiteId: %@", currentSiteId);
[[FeedStore sharedStore] setCurrentSiteId:currentSiteId];
//Now we can call fetchEntries
[self fetchEntries];
} else {
//If things went bad, show an alart view
UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Fel" message:@"Kunde inte bedömma din position relaterat till närmaste hållplats, försök gärna igen" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[av show];
//Stop UIRefreshControl
[refreshControl endRefreshing];
}
}];
}
然后调用 fetchEntries:
- (void)fetchEntries
{
void (^completionBlock)(RSSChannel *obj, NSError *err) = ^(RSSChannel *obj, NSError *err) {
if (!err) {
//If everything went ok, grab the object, and reload the table and end refreshControl
channel = obj;
//Post notification to refreshTableView method which will reload tableViews data.
[[NSNotificationCenter defaultCenter] postNotificationName:@"RefreshTableView" object:nil];
//Stop UIRefreshControl
[refreshControl endRefreshing];
} else {
//If things went bad, show an alart view
UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Fel" message:@"Kunde inte hämta avgångar för din hållplats, försök gärna igen" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[av show];
//Stop UIRefreshControl
[refreshControl endRefreshing];
}
};
//Initiate the request...
if (fetchType == ListViewControllerFetchBus) {
[[FeedStore sharedStore] fetchDepartures:completionBlock];
selectedSegment = 0;
} else {
[[FeedStore sharedStore] fetchDeparturesMetro:completionBlock];
selectedSegment = 1;
}
}
重新加载表:
- (void)refreshTableView:(NSNotification *)notif
{
[[self tableView] reloadData];
}
这是我填充自定义表格单元格的地方:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get received data from fetchEntries block
RSSItem *item = [[channel items] objectAtIndex:[indexPath row]];
//Get the new or recycled cell
ItemCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ItemCell"];
//Set the apperance
[[cell lineNumberLabel] setTextColor:[UIColor whiteColor]];
[[cell lineNumberLabel] minimumScaleFactor];
[[cell lineNumberLabel] setFont:[UIFont boldSystemFontOfSize:22]];
[[cell lineNumberLabel] adjustsFontSizeToFitWidth];
[[cell lineNumberLabel] setTextAlignment:NSTextAlignmentCenter];
[[cell destinationLabel] setTextColor:[UIColor whiteColor]];
[[cell displayTimeLabel] setTextColor:[UIColor whiteColor]];
[[cell displayTimeLabel] setTextAlignment:NSTextAlignmentLeft];
//Configure the cell with the item
if ([item lineNumber]) [[cell lineNumberLabel] setText:[item lineNumber]];
if ([item destination]) [[cell destinationLabel] setText:[item destination]];
if ([item displayTime]) [[cell displayTimeLabel] setText:[item displayTime]];
if ([item displayRow1]) [[cell destinationLabel] setText:[item displayRow1]];
return cell;
}
因此,当我在正常状态下穿过这些街区时,一切都像魅力一样。
但是当我从 UIActionSheet 或实际上从 UISegmentedControl(它是 UIActionSheet 的子视图)调用 fetchSite 方法时,问题就开始了,这发生在这里:
- (void)displayPickerView
{
//First im creating an instance to PickerViewController which will handle the UIPickerView which is a subview of UIActionSheet. pickerArrayFromChannel holds entries for UIPickerView to show in its ViewController.
pickerViewController = [[PickerViewController alloc] init];
[pickerViewController initWithItems: pickerArrayFromChannel];
pickerViewController.delegate = self;
//initiate UIActionSheet which needs no delegate or appearance more than its style
actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:nil
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
//Create frame and initiate a UIPickerView with this. Set its delegate to the PickerViewController and set it to start at row 0
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
pickerView.showsSelectionIndicator = YES;
pickerView.delegate = pickerViewController;
pickerView.dataSource = pickerViewController;
[pickerView selectRow:0 inComponent:0 animated:YES];
//Add this pickerView as subview to actionSheet
[actionSheet addSubview:pickerView];
//Now, create two buttons, closeButton and okButton. Which really are UISegmentedControls. Action to closeButton is (for now) dismissActionSheet which holds only following code " [actionSheet dismissWithClickedButtonIndex:0 animated:YES]; " and works fine
UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:@"Stäng"]];
closeButton.momentary = YES;
closeButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
closeButton.segmentedControlStyle = UISegmentedControlStyleBar;
closeButton.tintColor = [UIColor blackColor];
[closeButton addTarget:self action:@selector(dismissActionSheet) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:closeButton];
//OK button
UISegmentedControl *okButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:@"Visa avgångar"]];
okButton.momentary = YES;
okButton.frame = CGRectMake(10, 7.0f, 100.0f, 30.0f);
okButton.segmentedControlStyle = UISegmentedControlStyleBar;
okButton.tintColor = [UIColor blueColor];
[okButton addTarget:self action:@selector(updateDeparturesFromActionSheet) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:okButton];
//Now show actionSheet
[actionSheet showInView:[[UIApplication sharedApplication] keyWindow]];
[actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
}
现在让我们看看 updateDeparturesFromActionSheet 方法,我们正在接近我的问题开始的地方(如果你还在阅读,谢谢你
- (void)updateDeparturesFromActionSheet
{
//Dismiss the actionSheet
[actionSheet dismissWithClickedButtonIndex:0 animated:YES];
//Send the selected entry from UIPickerView to currentAddress property in FeedStore, fetchSite method will eventually use this
[[FeedStore sharedStore] setCurrentAddress:[pickerViewController addressFromPickerView]];
//Call fetchSite method
[self fetchSite];
}
fetchSite 然后最终调用 fetchEntries 方法,该方法最终填充我的表。我将收到的 obj(来自块)存储在一个名为 channel 的属性中
void (^completionBlock)(RSSChannel *obj, NSError *err) = ^(RSSChannel *obj, NSError *err) {
if (!err) {
//If everything went ok, grab the object, and reload the table and end refreshControl
channel = obj;
通道对象如下所示
channel RSSChannel * 0x07464340
NSObject NSObject
currentString NSMutableString * 0x00000000
lvc ListViewController * 0x08c455d0
items NSMutableArray * 0x08c452d0
sites NSMutableArray * 0x08c452f0
parentParserDelegate id 0x00000000
pickerViewArray NSMutableArray * 0x08c45320
正如您在填充表格单元格时所看到的那样,我使用来自通道对象内部项目的信息。
现在,如果到目前为止你还和我在一起(并且还没睡着),我将解释我的实际问题,现在当你(希望)拥有所有相关代码时。
因此,当我在 UIActionSheet 中按下okButton时,会调用 updateDeparturesFromActionSheet 方法。哪个调用 fetchSite 最终调用 fetchEntries 到目前为止一切都很好,这些块执行并且我得到了信息。但是当我抓取 fetchEntries obj并将其放入channel时,它似乎并没有用块obj对象抓取的新信息“更新”这个对象。其中,通道对象似乎没有在内存中获得新的位置(它保持 0x07464340)。我的第一个想法是确保频道对象被 ARC 通过删除该对象的所有所有者来释放,但似乎即使我这样做(然后用简单的 NSLog(@"%@") 再次检查它的空值,它也会不断获取它的旧值和内存引用当我触发“更新”时。
经过多次尝试释放通道对象并做各种事情(创建新数组(块外)等等)。我一直在想,我不理解的块中的一些特殊规则正在惹恼我。有任何想法吗?
如果有什么不清楚的地方请告诉我,因为我表达的很糟糕,很难解释一个你自己不理解的问题。先谢谢了。