首页 > 代码库 > 知识点

知识点

1.@synthesize@dynamic的差别


在声明property属性后,有2种实现选择

@synthesize

编译器期间,让编译器自己主动生成getter/setter方法。

当有自己定义的存或取方法时,自己定义会屏蔽自己主动生成该方法

 

@dynamic

告诉编译器。不自己主动生成getter/setter方法。避免编译期间产生警告

然后由自己实现存取方法

或存取方法在执行时动态创建绑定:主要使用在CoreData的实现NSManagedObject子类时使用,由Core Data框架在程序执行的时动态生成子类属性



2.假设一个网络请求类可能用到多次。可不能够用单例设计模式实现?


这个请求类仅仅是将不同的request请求作为參数传递到后方的服务接口。须要每个请求都new一个专门的对象来处理吗?如今我每个请求都new了一个对象来调后端服务接口,但考虑到请求数量非常多,pv非常大,所以看看能不能实现单例。


用单例主要是想节省内存资源,这个类主要是接受用户的不同请求调用后端接口返回不同的数据,只是实现单例不知道会不会出现其它的问题。。


~~对于接受请求的地方能够统一处理。然后把參数封装一层,扔给service,详细怎么处理须要依据业务来

假设用单例,你是想每次通过请求的參数 赋值么。假设不是,每次吧这个实例用了之后赋值为NULL

这个仅仅针对的是接收请求的地方吧,最多就多消耗一些资源。别的方面不会有多大的影响的,实现单例的时候最好考虑下多线程


3.初学iOS,刚看到控件的strong&weak问题。假设答的不正确还请指正。

首先有一点,在OC中。假设对象没有强引用。就会被自己主动释放,那么为什么控件还能够设为weak?

1. storyboard或者xib上创建控件。在控件放在view上的时候,已经形成了例如以下的引用关系,UIButton为例:UIViewController->UIView->subView->UIButton然后你为这个UIButton声明一个weak属性@property(nonatomic,weak) IBOOutlet UIButton *btn;

相当于xib/sb对这个Button是强引用,你声明的属性对它是弱引用。2.手动创建控件a).将控件声明成strong@property(nonatomic,strong) UIButton *btn;

那么你在实现这个控件时仅仅需这样:

_btn = [[UIButton alloc]init];

[self.view addSubview:_btn]

b). 将控件声明成weak@property(nonatomic,weak) UIButton *btn;

那么你在实现这个控件时须要这样:

UIButton *button = [[UIButton alloc]init];

_btn = button;

[self.view addSubview:_btn];


近期看的黑马iOS视频上给的建议的是:1.假设用Stroyboard拖线,用weak2.假设自定对象,用strong(但我还是习惯用weak临时=_=),事实上无论声明的属性是强引用还是弱引用,在控制器消失的时候,这个属性消失。View消失,subViews消失,控件也就消失了。


之前专门搜过相关的问题,贴上来:IBOutlet的属性一般能够设为weak是由于它已经被view引用了。除非view被释放。否则IBOutlet的属性也不会被释放。另外IBOutlet属性的生命周期和view应该是一致的。所以IBOutlet属性一般设为weak。可參考例如以下:

From a practical perspective, in iOS and OS X outlets should be defined as declared properties. Outlets should generally be weak, except for those from File’s Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets that you create will therefore typically be weak by default, because:Outlets that you create to, for example, subviews of a view controller’s view or a window controller’s window, are arbitrary references between objects that do not imply ownership.The strong outlets are frequently specified by framework classes (for example, UIViewController’s view outlet, or NSWindowController’s window outlet).

简单的说。假设IBOutlet对象是nib/sb scene的拥有者(File’s owner)所持有的对象。那么非常显然拥有者必须拥有对象的指针,因此属性应设置为strong。而其它的IBOutlet对象的属性须要设置为weak。由于拥有者并不须要拥有他们的指针。举例来说,UIViewControllerview属性是strong,由于controller要直接拥有view

而加入到view上的subviews,作为IBOutlet仅仅须要设置为weak就能够了。由于他们不是controller直接拥有的。直接拥有subviews的是controllerviewARC会帮助管理内存。紧接着,文档里又提到:

Outlets should be changed to strong when the outlet should be considered to own the referenced object:As indicated previously, this is often the case with File’s Owner—top level objects in a nib file are frequently considered to be owned by the File’s Owner.You may in some situations need an object from a nib file to exist outside of its original container. For example, you might have an outlet for a view that can be temporarily removed from its initial view hierarchy and must therefore be maintained independently.

第一种情形前面已经解释过了。对于另外一种,通俗点将,就是controller须要直接控制某一个subview而且将subview加入到其它的view tree上去。单纯从ARC的角度思考,用weak也是非常显然的:由于subview加入到view上时,view拥有”subview。当然,给IBOutlet属性设置为strong也没有错,纠结谁对谁错的问题可能须要上升到模式或者编码习惯的问题。已经超出本文的范围。


取消hits请求:App Transport Security Settings下Allow Arbitrary Loads置yes

enable bit code 置YES


子类实现父类方法,能够用在封装上面

父类确定时机,调用自己的实例方法,子类重写该方法


iOS_Copy究竟什么时候用?

A: 

OC里面有个值对象的概念。当你新定义一个属性是值对象时就应该用copy来修饰。那么都什么对象是值对象呢?

值对象:指封装了基本值(属于 C数据类型)且提供与该值相关的服务的对象。值对象以对象形式表示标量类型。Foundation框架向您提供了下面类(这些类产生对象,用于字符串、二进制数据、日期与时间、数字以及其它值):

NSStringNSMutableString ,  NSDataNSMutableData  ,  NSDate  ,   NSNumber   ,  NSValue


B: 

当一个指针运行的对象属性值发生改变时。不影响还有一个对象。那么须要分配两个不同的内存地址。也就是说,我们就不能够採用retainkeyword了。而是要採用copykeyword,由于copykeyword会在复制时又一次创建一个新的对象。

这里再提一下Copy:建立一个索引计数为1的对象,在赋值时使用传入值的一份拷贝。

(扩展:深拷贝[内存]和浅拷贝[指针]最大差别是什么?

:“主要看子类对象的地址是否一致”)


深拷贝和浅拷贝的理解?

总结:深拷贝拷贝的是内容,浅拷贝拷贝的是指针。深拷贝和浅拷贝最大的差别就是子类对象的地址是否改变,假设子类对象的地址改变那么就是深拷贝。

详解:

浅层复制(copy):仅仅复制指向对象的指针,而不复制引用对象本身。通过对象的指针来訪问这个对象----仅仅赋值地址

深层复制(mutableCopy):复制引用对象本身---再创建一个对象

意思就是有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,AA_copy指向的是同一个内存资源,复制的仅仅只是是是一个指针,对象本身资源还是仅仅有一份,那假设我们对A_copy运行了改动操作,那么发现A引用的对象相同被改动,这事实上违背了我们复制拷贝的一个思想。

深复制就好理解了,内存中存在了两份独立对象本身。

//当改动A,A copy不变。


我们在声明一个NSString属性时,对于其内存相关特性,通常有两种选择(基于ARC环境)strongcopy。那这两者有什么差别呢?什么时候该用strong,什么时候该用copy呢?让我们先来看个样例。

演示样例

我们定义一个类,并为其声明两个字符串属性,例如以下所看到的:

1

2

3

4 @interface TestStringClass ()

@property (nonatomic, strong) NSString *strongString;

@property (nonatomic, copy) NSString *copyedString;

@end

上面的代码声明了两个字符串属性。当中一个内存特性是strong,一个是copy。以下我们来看看它们的差别。

首先,我们用一个不可变字符串来为这两个属性赋值,

1

2

3

4

5

6

7

8 - (void)test {

    NSString *string = [NSString stringWithFormat:@"abc"];

    self.strongString = string;

    self.copyedString = string;

    NSLog(@"origin string: %p, %p", string, &string);

    NSLog(@"strong string: %p, %p", _strongString, &_strongString);

    NSLog(@"copy string: %p, %p", _copyedString, &_copyedString);

}

其输出结果是:

1

2

3origin string: 0x7fe441592e20, 0x7fff57519a48

strong string: 0x7fe441592e20, 0x7fe44159e1f8

copy string: 0x7fe441592e20, 0x7fe44159e200

我们要以看到,这样的情况下,无论是strong还是copy属性的对象。其指向的地址都是同一个,即为string指向的地址。

假设我们换作MRC环境,打印string的引用计数的话。会看到其引用计数值是3,即strong操作和copy操作都使原字符串对象的引用计数值加了1

接下来,我们把string由不可变改为可变对象,看看会是什么结果。

即将以下这一句

1NSString *string = [NSString stringWithFormat:@"abc"];

改成:

1NSMutableString *string = [NSMutableString stringWithFormat:@"abc"];

其输出结果是:

1

2

3origin string: 0x7ff5f2e33c90, 0x7fff59937a48

strong string: 0x7ff5f2e33c90, 0x7ff5f2e2aec8

copy string: 0x7ff5f2e2aee0, 0x7ff5f2e2aed0

能够发现。此时copy属性字符串已不再指向string字符串对象,而是深拷贝了string字符串。并让_copyedString对象指向这个字符串。在MRC环境下。打印两者的引用计数。能够看到string对象的引用计数是2。而_copyedString对象的引用计数是1

此时,我们假设去改动string字符串的话,能够看到:由于_strongStringstring是指向同一对象,所以_strongString的值也会尾随着改变(须要注意的是。此时_strongString的类型实际上是NSMutableString。而不是NSString);而_copyedString是指向还有一个对象的。所以并不会改变。

结论

因为NSMutableStringNSString的子类。所以一个NSString指针能够指向NSMutableString对象,让我们的strongString指针指向一个可变字符串是OK的。

而上面的样例能够看出,当源字符串是NSString时,因为字符串是不可变的。所以,无论是strong还是copy属性的对象。都是指向源对象。copy操作仅仅是做了次浅拷贝。

当源字符串是NSMutableString时,strong属性仅仅是添加了源字符串的引用计数。而copy属性则是对源字符串做了次深拷贝。产生一个新的对象,且copy属性对象指向这个新的对象。另外须要注意的是,这个copy属性对象的类型始终是NSString。而不是NSMutableString。因此其是不可变的。

这里另一个性能问题,即在源字符串是NSMutableStringstrong是单纯的添加对象的引用计数。而copy操作是运行了一次深拷贝,所以性能上会有所差异。而假设源字符串是NSString时,则没有这个问题。

所以。在声明NSString属性时。究竟是选择strong还是copy,能够依据实际情况来定。

只是。一般我们将对象声明为NSString时。都不希望它改变,所以大多数情况下,我们建议用copy。以免因可变字符串的改动导致的一些非预期问题。

关于字符串的内存管理,还有些有意思的东西。能够參考NSString特性分析学习


我先说下你两个代码的差别,第一个。当button 从试图移除之后不会释放。由于有强引用类型指向它。所以假设不再次释放一下,这个引用计数就是1

第二个,假设从父试图移除,这个button就直接释放了。由于是弱引用,弱引用不正确引用计数造成影响


何时使用的问题,假设一个对象在某段时间中重复载入,而你又不希望每次载入都要又一次alloc的话,那就strongstrong保证对此对象保持一个强引用,对于这个对象。仅仅要有1strong引用的话,那它就不会释放。当然多个strong同一时候作用于它也不会释放。


假设一个对象在某段时间仅仅会载入一次,而且载入之后确定不再使用了。那就能够使用weak,这样当其它原因导致引用计数减1(比方 removefromsuperview)的时候。此对象就自己主动释放了。无需再在delloc里面再release一次,但你要保证释放之后确实不再使用此对象,否则将导致错误


事实上strongretina的作用有些像。仅仅只是strongweak是在arc里面引入的,他俩算是一对儿。相应关系有点类似 retiamassign 


知识点