iOS笔记—对象的结构体属性单个修改方式
2017-04-06 13:56
549 查看
Objective-C语法规定,对象的结构体属性不能单个修改。如果是单独定义的结构体属性则可以单个修改。如象的结构体属性:
如单独定义的结构体属性:
对象的结构体属性不能单个修改,但是可以整体修改:
因此,我们想修改对象的结构体属性的单个属性的时候,可以采用先定义一个临时结构体变量,然后将对象的结构体属性整体赋给临时结构体变量。再在临时结构体变量中修改单个变量。最后再将整个临时变量的属性全部赋给对象结构体属性。就可以达到修改对象结构体单个属性的需求了。如:
再理清楚一下对象的结构体属性不能单个修改的原理:
在讲之前先要提前注意一点,在view.frame.size.width中,
view是一个Objective-C对象,因此view.frame是Objective-C语法,
frame是一个CGRect结构体,因此frame.size.width是C语言语法,因此这句话中是Objective-C与C同时混用的写法。(有些人可能平时理解的混用是指定义一些C类型的变量如int之类的,而忽略了其实Objective-C和C是可以连着混用的)。这里我们要理清楚一下Objective-C和Cd区别。Objective-C与C最主要得区别是Objective-C在原始的C语言主题上加入面向对象的概念。
Objective-C是C语言的母集合,意指任何原始的C语言程式都可以通过Objective-C编译器而不需要修改,也允许Objective-C使用任何原始的C语言代码。
可能有些人在刚学习在Objective-C语法时记得比较清楚些。Objective-C的点语法其实是一种语法糖,它只是方便了学习其他语言的人转过来学习Objective-C时更容易上手。对于view.frame 实际上会被转义为消息传递的形式[view frame]。而frame.size.width则以C语言的语法为基础,直接可以点出来的。所以view.frame.size.width = 20会变成[view frame].size.width= 20;将Objective-C消息传递转换成C语言的函数调用形式,则变成getFrame().size.width
= 20;写到这里我们就比较清楚的发现,它是一个getter方法,getter方法是并不能赋值的,因此我们将值赋给getter方法时,通过层层转义的xcode编译器会发出错误提醒,提示"expression is not assignable"(表达式不可赋值)
至此,我们已经解决了view.frame.size.width = 20;语法报错的问题以及它报错的原因。既然我们已经明白了原理,知道强扭的瓜不甜(连续点对象的结构体单独的属性肯定不能赋值)。那我们就不要强扭吧。
从上文一开始我们就讲对象的结构体属性不能单个修改,但是可以整体修改。所以,我们可以自己新建一个category重写一下结构体的setter和getter方法,用整体修改的办法去修改:
然后我们就可以使用 [view setWidth:20];去单独设置size的width了。其实xcode会自动帮我们生成setter和getter方法,所以更简洁的写法是:
self.view.frame.size.width = 10;// 编译器报错"expression is not assignable"
如单独定义的结构体属性:
CGSize mySize; mySize.width = 9; // 不报错
对象的结构体属性不能单个修改,但是可以整体修改:
view.frame=CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height);
因此,我们想修改对象的结构体属性的单个属性的时候,可以采用先定义一个临时结构体变量,然后将对象的结构体属性整体赋给临时结构体变量。再在临时结构体变量中修改单个变量。最后再将整个临时变量的属性全部赋给对象结构体属性。就可以达到修改对象结构体单个属性的需求了。如:
view.frame=CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height);CGRect hhgframe = view.frame;
hhgframe.size.width = 20;
view.frame = hhgframe;
再理清楚一下对象的结构体属性不能单个修改的原理:
在讲之前先要提前注意一点,在view.frame.size.width中,
view是一个Objective-C对象,因此view.frame是Objective-C语法,
frame是一个CGRect结构体,因此frame.size.width是C语言语法,因此这句话中是Objective-C与C同时混用的写法。(有些人可能平时理解的混用是指定义一些C类型的变量如int之类的,而忽略了其实Objective-C和C是可以连着混用的)。这里我们要理清楚一下Objective-C和Cd区别。Objective-C与C最主要得区别是Objective-C在原始的C语言主题上加入面向对象的概念。
Objective-C是C语言的母集合,意指任何原始的C语言程式都可以通过Objective-C编译器而不需要修改,也允许Objective-C使用任何原始的C语言代码。
可能有些人在刚学习在Objective-C语法时记得比较清楚些。Objective-C的点语法其实是一种语法糖,它只是方便了学习其他语言的人转过来学习Objective-C时更容易上手。对于view.frame 实际上会被转义为消息传递的形式[view frame]。而frame.size.width则以C语言的语法为基础,直接可以点出来的。所以view.frame.size.width = 20会变成[view frame].size.width= 20;将Objective-C消息传递转换成C语言的函数调用形式,则变成getFrame().size.width
= 20;写到这里我们就比较清楚的发现,它是一个getter方法,getter方法是并不能赋值的,因此我们将值赋给getter方法时,通过层层转义的xcode编译器会发出错误提醒,提示"expression is not assignable"(表达式不可赋值)
至此,我们已经解决了view.frame.size.width = 20;语法报错的问题以及它报错的原因。既然我们已经明白了原理,知道强扭的瓜不甜(连续点对象的结构体单独的属性肯定不能赋值)。那我们就不要强扭吧。
从上文一开始我们就讲对象的结构体属性不能单个修改,但是可以整体修改。所以,我们可以自己新建一个category重写一下结构体的setter和getter方法,用整体修改的办法去修改:
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
然后我们就可以使用 [view setWidth:20];去单独设置size的width了。其实xcode会自动帮我们生成setter和getter方法,所以更简洁的写法是:
UIView+Extension.h @interface UIView (Extension) @property (nonatomic, assign) CGFloat x; @property (nonatomic, assign) CGFloat y; @property (nonatomic, assign) CGFloatwidth; @property (nonatomic, assign) CGFloatheight; @property (nonatomic, assign) CGSize size; @property (nonatomic, assign) CGPointorigin; @end
相关文章推荐
- 【iOS开发-40】不能直接修改对象的结构体属性的成员,那怎么办?
- OC对象里面包含的结构体类型的属性,不能对该结构体属性的成员单个进行修改
- iOS中的数据持久化方式,基本上有以下四种:属性列表、对象归档、SQLite3和Core Data
- OC中修改 对象的结构体属性
- iOS学习笔记44-IOS 遍历未知对象的属性和方法
- Objective-C 【OC语法:不能修改 某个对象的 结构体属性的 成员】
- iOS笔记--iOS对象之间通信方式有哪些?
- 不允许直接修改对象的结构体属性的成员
- 学校学习ios教程笔记,第七节swift中的类与对象的属性和懒加载
- OCDay2-NSString、常见错误、结构体为属性时的访问、对象访问变量与方法的方式、#pragma mark\
- iOS 【transform属性】-通过tramsform熟悉个可以修改对象的平移、缩放比例和旋转角度
- JavaScript笔记 - 对象继承的几种方式
- (学习笔记)在ActionScript代码中重置对象的属性和样式
- 使用反射修改对象属性注意事项
- JavaScript prototype属性与修改对象
- JavaScript prototype属性与修改对象
- 如何通过修改快捷方式目标属性加载插件
- 写一个方法进行各种属性的更新,而不要每个界面设置改变都改变一个属性。就是点击应用或确定按钮时调用这个更新属性的方法,遍历所有(控制对象属性的)界面控件的状态(值),进行属性修改和刷新。
- PowerDesigner12.5修改数据库时,出现“对象无效。不允许有扩展属性,或对象不存在。SQLSTATE=37000” 的问题
- C#利用反射获取对象属性的修改情况