iOS结构体属性修改那些事儿
2019-06-05 本文已影响0人
往事不许提
相信很多同学在iOS开发过程中都遇到过这种情况:
// 直接给结构体赋值 OK
self.tableView.frame = CGRectMake(0,0,WIDTH,HEIGHT);
// 直接给结构体的属性赋值 报错:Expression is not assignable
self.tableView.frame.origin.x = 20;
// 直接给结构体的属性赋值 OK
CGSize size = CGSizeMake(20, 30);
size.width = 40;
问题:上面的self.tableView.frame和size都是结构体,也都是修改结构体的属性,为什么一个报错,一个正常?
答:
- 作为对象属性的结构体不能直接修改该结构体的属性,只能整体修改该结构体;
- 独立的结构体可以直接修改该结构体的属性;
通常我们这样修改作为对象属性的结构体:
view.frame=CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height);
CGRect newFrame = view.frame;
newFrame.size.width = 20;
view.frame = newFrame;
写起来着实难受,这么难受不想知道难受的原因吗?为什么不能直接修改呢?
揭开神秘面纱
- 先看报错: Expression is not assignable 。
- 啥意思? 表达式不可赋值。
- 啥表达式? self.tableView.frame.origin.x = 20 。
- 这个表达式完整的写法:[[self tableView] frame].origin.x = 20。
- 能理解不?前面两个点是OC的点语法糖,表示该属性的getter方法,后面的点是C语言中的结构体语法,大家都知道getter方法是不能赋值的,setter方法才是赋值的,所以报错:Expression is not assignable。
知其然,也知其所以然,Then what should we do ?
创建基于UIView的分类UIView+Extension.h:
UIView+Extension.h
@interface UIView (Extension)
-setWidth(CGFloat)width;
-(CGFloat)width;
@end
UIView+Extension.m
@implementation UIView (Extension)
- (void)setWidth:(CGFloat)width{
CGRect frame = self.frame;
frame.size.width = size.width;
self.frame = frame;
}
- (CGFloat)width{
return self.frame.size.width;
}
@end
代码中引入分类,畅快使用!