婚庆 wordpress,福州seo视频,课程网站建设,简述网站建设的具体步骤Q:ARC下#xff0c;不显式指定任何属性关键字时#xff0c;默认的关键字都有哪些#xff1f;
对应基本数据类型默认关键字是:atomic,readwrite,assign 对于普通的 Objective-C 对象:atomic,readwrite,strong
Q#xff1a;atomic 修饰的属性是怎么样保存线程安全的#x…
Q:ARC下不显式指定任何属性关键字时默认的关键字都有哪些
对应基本数据类型默认关键字是:atomic,readwrite,assign 对于普通的 Objective-C 对象:atomic,readwrite,strong
Qatomic 修饰的属性是怎么样保存线程安全的
答编译器会自动生成互斥锁对 setter 和 getter 方法进行加锁可以保证属性的赋值和取值原子性操作是线程安全的但不包括操作和访问。 比如说atomic修饰的是一个数组的话那么我们对数组进行赋值和取值是可以保证线程安全的。但是如果我们对数组进行操作比如说给数组添加对象或者移除对象是不在atomic的负责范围之内的所以给被atomic修饰的数组添加对象或者移除对象是没办法保证线程安全的。
Q什么情况使用 weak 关键字相比 assign 有什么不同
答 在 ARC 中在有可能出现循环引用的时候往往要通过让其中一端使用 weak 来解决比如: delegate、block。 自身已经对它进行一次强引用没有必要再强引用一次此时也会使用 weak自定义 IBOutlet 控件属性一般也使用 weak使用 storyboardxib 不行创建的 vc会有一个叫 _topLevelObjectsToKeepAliveFromStoryboard 的私有数组强引用所有 top level 的对象所以这时即便 outlet 声明成 weak 也没关系。当然也可以使用 strong。 weak 和 assign 的不同点 ① weak只能修饰对象而assign既可以修饰对象也可以修饰基本数据类型 ② assign修饰的对象在被释放后指针仍然指向原对象地址而weak修饰的对象在被释放之后会自动置指针为 nil ③ 相同点在修饰对象的时候assign和weak都不改变对象的引用计数。
Qweak修饰的释放则自动被置为nil的实现原理
答weak 实现原理的概括 Runtime维护了一个weak表用于存储指向某个对象的所有weak指针。weak表其实是一个hash哈希表Key是所指对象的地址Value是weak指针的地址这个地址的值是所指对象的地址数组。
weak 的实现原理可以概括一下三步
1、初始化时runtime会调用objc_initWeak函数初始化一个新的weak指针指向对象的地址。 2、添加引用时objc_initWeak函数会调用 objc_storeWeak() 函数 objc_storeWeak() 的作用是更新指针指向创建对应的弱引用表。 3、释放时调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组然后遍历这个数组把其中的数据设为nil最后把这个entry从weak表中删除最后清理对象的记录。
Q:为什么iOS开发中控件一般为weak而不是strong?
IBOutlet的属性一般可以设为weak是因为它已经被view引用了除非view被释放否则IBOutlet的属性也不会被释放另外IBOutlet属性的生命周期和view应该是一致的所以IBOutlet属性一般设为weak。 简单的说如果IBOutlet对象是nib/xib scene的拥有者File’s owner所持有的对象那么很显然拥有者必须“拥有”对象的指针因此属性应设置为strong。而其他的IBOutlet对象的属性需要设置为weak因为拥有者并不需要“拥有”他们的指针。
答因为view被添加到superView上面后就被superView持有了。我们一般在IB里面的拖的view都是加在了根view或者它的子view上。而根view又被它的controller持有所以IBOutlet可以用weak。如果在IB里面拖出来的view是一个单独的view没有被加到任何其他view上则需要用strong。
Q以下代码会出现什么问题深浅拷贝
property (copy) NSMutableArray *array; 答 1.把NSMutableArray用copy修饰有时就会crash因为对这个数组进行了增删改操作而copy后的数组变成了不可变数组NSArray没有响应的增删改方法所以对其进行增删改操作就会报错。 2.默认atomic修饰编译器会自动生成互斥锁对 setter 和 getter 方法进行加锁操作这个过程会消耗一些性能,执行效率慢一般使用nonatomic修饰
Q:用property声明的NSString或NSArrayNSDictionary经常使用copy关键字为什么如果改用strong关键字可能造成什么问题
1.因为父类指针可以指向子类对象,使用 copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本. 2.如果我们使用是 strong ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性. copy 此特质所表达的所属关系与 strong 类似。然而设置方法并不保留新值而是将其“拷贝” (copy)。
Q:property 的本质是什么ivar、getter、setter 是如何生成并添加到这个类中的
property的本质是 ivar(实例变量) getter setter.
attributes的具体内容包含: 类型, 原子性, 内存语义和对应的实例变量.
我们每次在增加一个属性, 系统都会在 ivar_list 中添加一个成员变量的描述, 在 method_list 中增加 setter 与 getter 方法的描述, 在属性列表中增加一个属性的描述, 然后计算该属性在对象中的偏移量, 然后给出 setter 与 getter 方法对应的实现, 在 setter 方法中从偏移量的位置开始赋值, 在 getter 方法中从偏移量开始取值, 为了能够读取正确字节数, 系统对象偏移量的指针类型进行了类型强转.
Q:weak属性需要在dealloc中置nil么
不需要。 在ARC环境无论是强指针还是弱指针都无需在 dealloc 设置为 nil ARC 会自动帮我们处理 即便是编译器不帮我们做这些weak也不需要在 dealloc 中置nil因为在属性所指的对象遭到摧毁时属性值也会清空(nil out)。 当一个被weak修饰的对象被释放后weak对象怎么处理的 清除weak变量同时设置指向为nil。当对象被dealloc释放后在dealloc的内部实现中会调用弱引用清除的相关函数会根据当前对象指针查找弱引用表找到当前对象所对应的弱引用数组将数组中的所有弱引用指针都置为nil。
Q:说说你理解weak属性
Runtime维护了一个weak表用于存储指向某个对象的所有weak指针。weak表其实是一个hash哈希表Key是所指对象的地址Value是weak指针的地址这个地址的值是所指对象的地址数组。 1、初始化时runtime会调用objc_initWeak函数初始化一个新的weak指针指向对象的地址。 2、添加引用时objc_initWeak函数会调用 objc_storeWeak() 函数 objc_storeWeak() 的作用是更新指针指向创建对应的弱引用表。 3、释放时调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组然后遍历这个数组把其中的数据设为nil最后把这个entry从weak表中删除最后清理对象的记录。 追问的问题一 1.实现weak后为什么对象释放后会自动为nil runtime 对注册的类 会进行布局对于 weak 对象会放入一个 hash 表中。 用 weak 指向的对象内存地址作为 key当此对象的引用计数为 0 的时候会 dealloc假如 weak 指向的对象内存地址是 a 那么就会以 a 为键 在这个 weak 表中搜索找到所有以 a 为键的 weak 对象从而设置为 nil 。 追问的问题二 2.当weak引用指向的对象被释放时又是如何去处理weak指针的呢 1、调用objc_release 2、因为对象的引用计数为0所以执行dealloc 3、在dealloc中调用了_objc_rootDealloc函数 4、在_objc_rootDealloc中调用了object_dispose函数 5、调用objc_destructInstance 6、最后调用objc_clear_deallocating,详细过程如下 a. 从weak表中获取废弃对象的地址为键值的记录 b. 将包含在记录中的所有附有 weak修饰符变量的地址赋值为 nil c. 将weak表中该记录删除 d. 从引用计数表中删除废弃对象的地址为键值的记录 10.iOS本地数据存储安全 11.BAD_ACCESS的错误吗你是怎样调试的 BAD_ACCESS不管什么时候当你遇到BAD_ACCESS这个错误那就意味着你向一个已经释放的对象发送消息。 BAD_ACCESS的本质 在C和OC中你一直在处理指针指针无非是存储另一个变量的内存地址的变量。当向一个对象发送消息时指向该对象的指针将会被引用这意味着你获取了指针所指的内存地址并访问该存储区域的值。 当该存储器区域不再映射到你的应用时或者换句话说该内存区域在你认为使用的时候没有使用该内存区域是无法访问的这时内核会抛出一个异常(EXC)表明你的应用程序不能访问该存储器区域(BAD_ACCESS). 当你碰到BAD_ACCESS这意味着你试图发送消息到的内存块但内存块无法执行该消息。但是在某些情况下BAD_ACCESS是由被损坏的指针引起的每当你的应用程序尝试引用损坏的指针一个异常就会被内核抛出。
Q:synthesize和dynamic分别有什么作用
1.property有两个对应的词一个是 synthesize一个是 dynamic。如果 synthesize和 dynamic都没写那么默认的就是syntheszie var _var; 2.synthesize 的语义是如果你没有手动实现 setter 方法和 getter 方法那么编译器会自动为你加上这两个方法。 3.dynamic 告诉编译器属性的 setter 与 getter 方法由用户自己实现不自动生成。当然对于 readonly 的属性只需提供 getter 即可。假如一个属性被声明为 dynamic var然后你没有提供 setter方法和 getter 方法编译的时候没问题但是当程序运行到 instance.var someVar由于缺 setter 方法会导致程序崩溃或者当运行到 someVar var 时由于缺 getter 方法同样会导致崩溃。
///
property有两个关键词, synthesize(默认值)和dynamic. synthesize表示系统会默认添加一个syntheszie var _var的实例变量, 并且自动生成setter和getter方法. synthesize 合成实例变量有以下几点规则: 如果指定了成员变量的名称, 会生成一个指定的名称的成员变量. 如果这个成员已经存在就不再生成了. 如果没有指定成员变量的名称会自动生成一个属性同名的成员变量. synthesize的使用场景: 同时重写了setter和getter时 重写了只读属性的getter时 在使用了dynamic时 在Protocol和category中定义属性时 重载父类的属性时, 来手动合成Ivar(实例变量/成员变量). dynamic表示我们不需要系统自动生成, 由用户自己实现, 如果没有手动生成的话, 在使用过程中是会奔溃的.
Q:synthesize合成实例变量的规则是什么假如property名为foo存在一个名为_foo的实例变量那么还会自动合成新变量么
总结下 synthesize 合成实例变量的规则有以下几点 如果指定了成员变量的名称,会生成一个指定的名称的成员变量, 如果这个成员已经存在了就不再生成了. 如果是 synthesize foo; 还会生成一个名称为foo的成员变量也就是说 如果没有指定成员变量的名称会自动生成一个属性同名的成员变量, 如果是 synthesize foo _foo; 就不会生成成员变量了. 假如 property 名为 foo存在一个名为 _foo 的实例变量那么还会自动合成新变量么 不会。
Q:在有了自动合成属性实例变量之后synthesize还有哪些使用场景
什么情况下不会autosynthesis自动合成 同时重写了 setter 和 getter 时 重写了只读属性的 getter 时 使用了 dynamic 时 在 protocol 中定义的所有属性 在 category 中定义的所有属性 重载的属性 当你在子类中重载了父类中的属性你必须 使用 synthesize 来手动合成ivar。
synthesize 语法还有一个应用场景但是不太建议大家使用 可以在类的实现代码里通过 synthesize 语法来指定实例变量的名字
implementation CYLPerson synthesize firstName _myFirstName; synthesize lastName _myLastName; end
可变数组不可变数组修饰符的使用结论
当修饰可变类型的属性时如NSMutableArray、NSMutableDictionary、NSMutableString用strong。 当修饰不可变类型的属性时如NSArray、NSDictionary、NSString用copy。
深拷贝与浅拷贝
浅拷贝就是拷贝之后并没有真正的复制而是复制对象和原对象都指向同一个地址 深拷贝是真正的复制了一份复制的对象只想新的地址; copy对于可变对象为深拷贝对于不可变对象为浅拷贝; mutablecopy始终为深拷贝; 浅拷贝简单点说就是对内存地址的复制让目标对象指针和源对象指针指向同一片内存空间; 深拷贝: 内容拷贝会创建一个新的对象。深拷贝就是拷贝地址中的内容让目标对象产生新的内存区域且将源内存区域中的内容复制到目标内存区域中;
Q:objc中的类方法和实例方法有什么本质区别和联系
实例变量 成员变量 ivar 类方法 1. 类方法是属于类对象的 2. 类方法只能通过类对象调用 3. 类方法中的self是类对象 4. 类方法可以调用其他的类方法 5. 类方法中不能访问成员变量 6. 类方法中不定直接调用对象方法 实例方法 1. 实例方法是属于实例对象的 2. 实例方法只能通过实例对象调用 3. 实例方法中的self是实例对象 4. 实例方法中可以访问成员变量 5. 实例方法中直接调用实例方法 6. 实例方法中也可以调用类方法(通过类名)