Problem1
为什么对类 A 的 delegate 属性设置成weak 或者assgin 会deadlock 。但是换成strong 可以正常运行。
self 本身也是另外一个类的局部变量。
1
2
3
4
5
6
7
| - (void)createFilterBarFor:(AJKBSearchEstateViewController *)vc
{
AJKBrokerAPI *brokerAPI = [[AJKBrokerAPI alloc] init];
brokerAPI.delegate = self;
[brokerAPI sendGetFilterWordsRequest];
self.viewController = vc;
}
|
这时候delegate 所指的对象已经被释放掉了。所以运行到这里会出现 EXC_BAD_ACCESEX。像这类EXC_BAD_ACCESEX问题主要缘于access released objects。
1
2
3
| if ([self.delegate respondsToSelector:@selector(didLoadFilterItemsSuccess:)]) {
[self.delegate didLoadFilterItemsSuccess:filtersArrays];
}
|
一个正确的做法是将A类的实例,设置成B的property,然后保证 delegate 的属性 设置成weak or assign这样避免环形引用。如果一定要将其创建成一个B的局部变量,那么就得将A的delegate 属性创建成Strong,这样才不至于出现EXC_BAD_ACCESS。
Problem2
为什么程序运行到
1
| imageView.image = strongSelf.arrowImageViews[oppsiteIndex];
|
会crash 呢? 而且会不断 调用 imageView setImage 方法。是不是因为 迭代器里 block 执行时异步的?但是UI绘制时在主线程??
1
2
3
4
5
6
7
8
9
10
| __weak typeof(self) weakSelf = self;
[self.arrowImageViews enumerateObjectsUsingBlock:^(UIImageView *imageView, NSUInteger idx, BOOL *stop) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (idx == index) {
imageView.image = strongSelf.arrowImageViews[imageIndex];
} else {
NSInteger oppsiteIndex = imageIndex ^ 1;
imageView.image = strongSelf.arrowImageViews[oppsiteIndex];
}
}];
|
原因:低级错误,arrowImageViews (UIImageView 类型) 写错了,应该时arrowImags UIImage 类型
如果是UI代码已运行就crash,通常是因为传值类型不匹配导致的。
Problem3
在执行完之后,为什么self.emptyBackgroundView 还在其superView 中呢??
1
2
3
| if (self.emptyBackgroundView) {
[self.emptyBackgroundView removeFromSuperview];
}
|
但是通过po [self.view subviews] 发现有许多重复的 emptyBackgroundView view 加在了subview 数组里面,导致移除该 emptyBackgroundView ,还有很多 emptyBackgroundView。 所以看上去,好像是没有被remove掉。
出现这种情况是因为,[ self addSubView self.emptyBackground] api callBack 调用,多次请求之后会出现重复addSubview。这样view 的hierarchy重复的subview 会增加。
1
2
3
4
| <AJKBSearchNoResultView: 0x7a622da0; frame = (0 46; 320 478); layer = <CALayer: 0x7a65c300>>,
<AJKBSearchNoResultView: 0x7a626c50; frame = (0 46; 320 478); layer = <CALayer: 0x7a6f4660>>,
<AJKBSearchNoResultView: 0x7ac688f0; frame = (0 46; 320 478); layer = <CALayer: 0x7ac67f30>>,
<AJKBSearchNoResultView: 0x7ac69cf0; frame = (0 46; 320 478); layer = <CALayer: 0x7ac69d60>>,
|
通过手段改善:
1
2
3
| if (![self.view.subviews containsObject:self.emptyBackgroundView]){
[self.view addSubview:self.emptyBackgroundView];
}
|
Problem4
对于subview 比较复杂的页面,如果要保证某个view可见
可以使用
1
| [self.view bringSubviewToFront:self.tableView];
|
解决self.tableView 被遮挡的问题。
Problem5
如果是给UITablView 中delegate赋值A类的instance,一定得注意其UITableViewDelegate的方法和 UIScrollViewDelegate 方法只能在同一个类的instance中实现。
Problem6
1
2
3
4
| [tableView deselectRowAtIndexPath:indexPath animated:YES];
if (self.navigationController.view.frame.origin.x > 0) {
return;
}
|
Problem7
设置statusBar样式的方法
1
2
| [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
这是全局修改
|
设置navigationBar backgroundColor. iOS 7 和 iOS 6 有差异
1
2
3
4
5
6
| if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
self.navigationController.navigationBar.barTintColor = NAVIGATIONBAR_COLOR;
self.navigationController.navigationBar.translucent = YES;
} else {
self.navigationController.navigationBar.tintColor = NAVIGATIONBAR_COLOR;
}
|
Problem8
在TableView 试图回到最顶端,发现下面这个方法非常不稳定
1
| [self.tableView setContentOffset:CGPointZero animated:YES];
|
换成下面这个方法
1
2
| NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
|
Problem9
UIViewController.view 其高度在 viewDidLoad 中ViewWillAppear 中是不同的。ViewWillAppear view 的高度已经去掉statusBar 和navigationBar 的高度。