iOS开发中由属性(property)引发的坑
来源:互联网 发布:aftereffects软件下载 编辑:程序博客网 时间:2024/05/16 17:54
copy修饰的NSMutableArray属性(property)初始化问题
对于属性:
@property (nonatomic, copy) NSMutableArray *someArray;
若初始化时使用self.someArray:
self.someArray = [[NSMutableArray alloc] initWithCapacity:200];
当使用:
[self.someArray addObject:name];
APP Crash,其中关键 Error Info如下:
-[__NSArrayI addObject:]: unrecognized selector sent to instance 0x7f9c89701c20
原因是,通过copy修饰的property,若通过self.someArray =
来赋值初始化,则是通过系统合成setter方法实现,由于设置copy修饰词,则返回实际上是不可变数组(NSArray),当调用addObject 方法会报错。
初始化
或者 赋值
部分,做如下修改:
_someArray = [[NSMutableArray alloc] initWithCapacity:200];
则APP运行正常,原因是:
_someArray是实例变量,实例变量并没有 copy 修饰,指向的仍是定义的 NSMutableArray 类型。所以即使后面通过 self.someArray 使用 addObject方法仍然可行,因为初始化赋值阶段获取的是NSMutableArray类型对象
知道最佳解决方案么? 其实,就是把
copy
修饰词改为strong
,因为可变数组对象是个容器,只要其元素中没有和self对象存在相互持有造成内存泄漏的,则不会出现任何问题。
@synthesize @dynamic 正确使用
在之前的文章 Objective-C 2.0 基础要点归纳 中,对属性(property)进行了分析,但没有对关键字 @property 和 @synthesize 以及@dynamic的作用进行对比解析,这部分将对之进行详细分析,但问题却是因 atomic 修饰词引出。
关键字的作用说明
- @property 预编译命令(关键字)作用是声明属性的 getter和setter方法
- @synthesize 生成属性访问器即 getter和setter方法
- @dynamic 禁止编译器生成 getter/setter,通过自定义或者在运行时动态创建绑定:主要使用在Core Data中
atomic 是操作原子性,作为属性修饰词,则编译器生产的 getter/setter方法中存在 @synchronized(self)或者lock锁机制只允许原子性访问。
若只自定义一个属性访问器(setter/getter中一个),会出现warning:writable atomic property ‘name’ cannot pair a synthesized getter with …
若两个都定义,则需要 @synthesize name = _name; 两个都自定义的情况下,系统不会合成属性访问器,则此时需要显示调用 @synthesize来定义属性的实例变量名,以便使用属性的实例变量
实践代码:
TestAtomic 类
TestAtomic.h
#import <Foundation/Foundation.h>@interface TestAtomic : NSObject@property (atomic, copy) NSString *name;// 注意atomic修饰符@end
TestAutomic.m
#import "TestAtomic.h"@implementation TestAtomic@synthesize name = _name;- (NSString *)name{ if (![_name isEqualToString:@""]) { return _name; } else { return nil; }}- (void)setName:(NSString *)name{ @synchronized(self) { //类似于默认setter方法 if (![_name isEqualToString:name]) { _name = name; } }}@end
TestB 类,继承TestAtomic类
TestB.h
#import "TestAtomic.h"@interface TestB : TestAtomic@property (atomic, copy) NSString *Bname;- (instancetype)initWithSuperName;- (void)print;@end
TestB.m
#import "TestB.h"@implementation TestB- (instancetype)initWithSuperName{ self = [super init]; if (self) { [self setName:@"this is A"]; } return self;}- (void)print{ NSLog(@"%@ --- %@", self.Bname, self.name);}@end
Main 函数:
#import <Foundation/Foundation.h>#include "TestAtomic.h"#include "TestB.h"int main(int argc, const char * argv[]){ @autoreleasepool { TestB *testB = [TestB new]; testB.name = @"this is good"; //testB = [testB initWithSuperName]; testB.Bname = @"this is B"; [testB print]; }return 0;}
参考资源
NSMutableArray问题
error: writable atomic property cannot pair a synthesized setter/getter
iphone 开发中属性 property 和 synthesize 权威的介绍
iOS中atomic的实现解析
@synthesize和@dynamic区别
- iOS开发中由属性(property)引发的坑
- ios开发中@property的属性介绍
- ios开发中@property的属性介绍
- iOS开发中@property的属性介绍
- iOS开发中@property的属性介绍
- iOS开发中@property的属性介绍
- iOS开发中@property的属性介绍
- iOS开发中@property的属性介绍
- iOS开发中@property的属性介绍
- iOS开发中@property的属性介绍
- iOS开发中@property的属性介绍
- iOS开发中@property的属性介绍
- ios开发中@property的属性介绍
- iOS开发中@property的属性介绍
- iOS开发中@property的属性介绍
- iOS开发中@property的属性介绍
- 【iOS】iOS开发中@property的属性介绍
- iOS开发中属性 property 和 synthesize 权威的介绍
- c/c++编译时,指定程序运行时查找的动态链接库路径
- 常用排序算法稳定性、时间复杂度分析(转,有改动)
- 实用工具—SimpleMind 和Sublime Text
- MySQL索引类型以及创建
- 20150816 Bootstrap入门
- iOS开发中由属性(property)引发的坑
- 黑马程序员-[OC语言] 第一篇:类、对象的基本概述
- Python优秀函数库集锦(一)
- Combination Sum III
- 算法竞赛入门经典:第六章 数据结构基础 6.2铁轨
- android自带浏览器修改主页和收藏页
- DFS-HDU-1241-Oil Deposits
- 算法竞赛入门经典:第六章 数据结构基础 6.3移动小球
- 记糊涂了,下次真的有必要脑补一下“id和name”在前台页面中的作用