iOS基础知识

1.对属性修饰符的理解

MRC下

assign

主要用于修饰基本数据类型,setter方法也只是简单的赋值,例如NSInter,CGFloat 如果用来修饰对象,并不持有对象,那么对象的引用计数不变,如果这个时候对象被释放了,他就可能成为野指针,不手动置为nil,在堆上很容易造成崩溃,而如果修饰的不是对象,那么栈上的内存系统会自动处理,不会造成野指针

retain

修饰对象,不能修饰基本数据类型 ,引用计数+1,适用于NSObject及子类

ARC下

Strong

对应的setter方法是先release,然后再把参数retain,最后成员变量赋值,类似于retain

表示指向并拥有对象,其修饰的对象引用计数会+1,该对象只要引用计数不为0则不会被销毁,当然强行置为nil可以销毁他

Copy

对应的setter方法是先release,然后copy参数内容,创建一个新的内存地址,因此修改之前的地址不会修改到副本,减少对上下文的依赖,copy一般用于修饰具有可变应用类型的不可变对象身上,例如NSArray,NSString,NSDictionary,,为什么呢?看下例子

    @property(nonatomic,strong) NSString *testStrongName;
    @property(nonatomic,copy) NSString * testCopyName;
 
    self.testStrongName = @"test1";
    self.testCopyName = @"test1";
    NSLog(@"strong====%@    p==== %p",self.testStrongName,self.testStrongName);
    NSLog(@"copy======%@    p==== %p",self.testCopyName,self.testCopyName);

    NSMutableString *mStr = [[NSMutableString alloc]initWithString:@"TestM2"];
    self.testStrongName = mStr;
    self.testCopyName = mStr;
    NSLog(@"mStr==== %p",mStr);
    
    [mStr appendString:@"111"];//mstr不改地址
    
    NSLog(@"mStr==== %p",mStr);

    mStr = [NSMutableString stringWithFormat:@"test2"];//mstr改地址
    NSLog(@"mStr==== %p",mStr);

    [mStr appendString:@"111"];

    NSLog(@"strong====%@    p==== %p",self.testStrongName,self.testStrongName);
    NSLog(@"copy======%@    p==== %p",self.testCopyName,self.testCopyName);

    //打印结果为
   2019-01-22 11:42:33.286277+0800 OC-test1[18667:237712] [default] Unable to load   
   Info.plist exceptions (eGPUOverrides)
   2019-01-22 11:42:33.338443+0800 OC-test1[18667:237660] strong====test1    p==== 
   0x100002058
   2019-01-22 11:42:33.338476+0800 OC-test1[18667:237660] copy======test1    
   p==== 0x100002058
   2019-01-22 11:42:33.338495+0800 OC-test1[18667:237660] mStr==== 
   0x600000c053e0
   2019-01-22 11:42:33.338511+0800 OC-test1[18667:237660] mStr==== 
    0x600000c053e0
   2019-01-22 11:42:33.338535+0800 OC-test1[18667:237660] mStr==== 
   0x600000c05410
   2019-01-22 11:42:33.338569+0800 OC-test1[18667:237660] strong====TestM2111    
   p==== 0x600000c053e0
   2019-01-22 11:42:33.338584+0800 OC-test1[18667:237660] copy======TestM2    
   p==== 0x5f8f2f5af9a6eb4d

可以看到,本身是不可变类型NSString,但是它会有可变类型的属性在,如果你用Strong修饰他,当该指针指向了NSMutableString类型的数据,Strong只是把源数据的多了一个新的指针指向而已,当源数据改变,那么原来设置的name不可变类型,就可以变了。这就是上面遇到修改之前的数据改变了现有的数据,上下文依赖了,因此copy来减少上下文依赖,如果本身是不可变类型NSstring,那么Strong也一样,如果变成可变类型了,那么减少上下文依赖,copy就会对可变类型执行深copy,从而让数据源更干净

strong和copy都会使引用计数加1,但strong使两个指针指向同一个内存地址,copy则会在内存里拷贝一份对象,两个指针指向不同的内存地址

针对copy这个属性,以string类型为例,copy就是普通的指针copy(浅copy),而mutableCopy就是内容copy(深copy),如果是mutableString类型的话,那么copy就全是内容copy了 如果是容器类型,例如NSArray和NSDictionary,copy属性操作的指针针对容器本身,而容器内部的都还是同一个指针引用,并不会根据容器的copy或者strong而变化,指针根据自己的属性修饰符有关

  • weak 不会保留传入的属性,不会使对象的引用计数+1,类似assign,但是当对象被释放时,weak自动置nil,这就是weak区别assgin最大的区别 小知识:当属性是readwrite的时候,如果重写了getter的方法,那么setter方法是系统提供的,那么系统顺便帮我们实现了成员变量,但是如果你重写了setter和getter方法,那么这个时候你把系统的两个方法都实现了,那么系统就需要你自己去实现成员变凉了,不然是无法获取到的,你可以再implementation或者extension里面进行实现,或者在h文件实现,前两者是@private的,后者是共有的

weak 和 assign的理解

1.assign适用于基本数据类型,weak是适用于NSObject对象,并且是一个弱引用。 2.assign其实也可以用来修饰对象。那么我们为什么不用它修饰对象呢?因为被assign修饰的对象(一般编译的时候会产生警告:Assigning retained object to unsafe property; object will be released after assignment)在释放之后,指针的地址还是存在的,也就是说指针并没有被置为nil,造成野指针。对象一般分配在堆上的某块内存,如果在后续的内存分配中,刚好分到了这块地址,程序就会崩溃掉。 3.那为什么可以用assign修饰基本数据类型?因为基础数据类型一般分配在栈上,栈的内存会由系统自己自动处理,不会造成野指针。 4.weak修饰的对象在释放之后,指针地址会被置为nil。所以现在一般弱引用就是用weak。weak使用场景: 5.在ARC下,在有可能出现循环引用的时候,往往要通过让其中一端使用weak来解决,比如: delegate代理属性,通常就会声明为weak。 自身已经对它进行一次强引用,没有必要再强引用一次时也会使用weak。比如:自定义 IBOutlet控件属性一般也使用weak,当然也可以使用strong。

__block与__weak的区别

__block是用来修饰一个变量,这个变量就可以在block中被修改
__block:使用 __block修饰的变量在block代码块中会被retain(ARC下会retain,MRC下不会retain)
__weak:使用__weak修饰的变量不会在block代码块中被retain
同时,在ARC下,要避免block出现循环引用 __weak typedof(self)weakSelf = self;
这两个都是和block相关,block就是OC对闭包的实现,闭包就是匿名函数,或者理解为指向函数的指针
block变量定义时为什么用copy?block是放在哪里的?
block本身是像对象一样可以retain,和release。但是,block在创建的时候,它的内存是分配在栈(stack)上,可能被随时回收,而不是在堆(heap)上。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。通过copy可以把block拷贝(copy)到堆,保证block的声明域外使用。

特别需要注意的地方就是在把block放到集合类当中去的时候,如果直接把生成的block放入到集合类中,是无法在其他地方使用block,必须要对block进行copy。

[array addObject:[[^{
    NSLog(@"hello!");
} copy] autorelease]];

nil,Nil,NULL和NSNull理解

nil

nil 是 ObjC 对象的字面空值,对应 id 类型的对象,或者使用 @interface 声明的 ObjC 对象。
例如:

NSString *someString = nil;
NSURL *someURL = nil;
id someObject = nil;
if (anotherObject == nil) // do something

定义:

#ifndef nil
# if __has_feature(cxx_nullptr)
#   define nil nullptr
# else
#   define nil __DARWIN_NULL
# endif
#endif
 
// __DARWIN_NULL in _types.h
 
#define __DARWIN_NULL ((void *)0)
Nil

Nil 是 ObjC 类类型的书面空值,对应 Class 类型对象。
例如:

Class someClass = Nil;
Class anotherClass = [NSString class];

定义声明和 nil 是差不多的,值相同:

#ifndef Nil
# if __has_feature(cxx_nullptr)
#   define Nil nullptr
# else
#   define Nil __DARWIN_NULL
# endif
#endif
NULL

NULL 是任意的 C 指针空值。
例如:

int *pointerToInt = NULL;
char *pointerToChar = NULL;
struct TreeNode *rootNode = NULL;

定义:

// in stddef.h
 
#define NULL ((void*)0)
NSNull

NSNull 是一个代表空值的类,是一个 ObjC 对象。实际上它只有一个单例方法:+[NSNull null],一般用于表示集合中值为空的对象。
例子说明:

// 因为 nil 被用来用为集合结束的标志,所以 nil 不能存储在 Foundation 集合里。
NSArray *array = [NSArray arrayWithObjects:@"one", @"two", nil];
 
// 错误的使用
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:nil forKey:@"someKey"];
 
// 正确的使用
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:[NSNull null] forKey:@"someKey"];

定义:

NSNull.h
#import <Foundation/NSObject.h>
@interface NSNull : NSObject <NSCopying, NSSecureCoding>
+ (NSNull *)null;
@end
NIL 或 NSNil

ObjC 不存在这两个符号!

转载参考
iOS基础面试知识点总结 - Deft_MKJing的博客 - CSDN博客
nil,Nil,NULL和NSNull理解(ios)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354