当前位置: 首页 > news >正文

做网站 怎么发布广东东莞石碣今天新闻

做网站 怎么发布,广东东莞石碣今天新闻,qq群推广,广州aso优化第15条#xff1a;用前缀避免命名空间冲突 OC没有其他语言那种内置的命名空间机制。因此#xff0c;我们在起名时要设法避免潜在的命名冲突#xff0c;否则很容易就重名了。若是发生重名冲突#xff0c;那么应用程序相应的链接过程就会出错。例如#xff1a; 错误原因在…第15条用前缀避免命名空间冲突 OC没有其他语言那种内置的命名空间机制。因此我们在起名时要设法避免潜在的命名冲突否则很容易就重名了。若是发生重名冲突那么应用程序相应的链接过程就会出错。例如 错误原因在于应用程序中的两段代码都各自实现了名为EOCTheClass的类会导致该类所对应的类符号和“元类”符号各定义了两次。 你可能是把两个相互独立的程序库都导入到当前项目而它们又恰好有重名的类。 避免此问题的唯一办法就是变相实现命名空间为所有名称都加上适当前缀。所选前缀可以是与公司、应用程序或二者皆有关联之名。 使用Cocoa创建应用程序时一定要注意Apple宣称其保留使用所有“两字母前缀”的权利所以你自己选用的前缀应该是三个字母的。 不仅是类名应用程序中的所有名称都应加前缀。如果要为既有类新增“分类”那么一定要给“分类”及“分类”中的方法加上前缀。开发者可能会忽视另外一个容易引起命名冲突的地方那就是类的实现文件中所用的纯C函数及全局变量在编译好的目标文件中这些名称是要算做“顶级符号”的。 并且每个类中相应的方法也应该有该类相应的前缀用以分别该类和其他类中的名称相同的方法。这样做还有个好处就是若此符号出现在栈回溯信息中那么我们就很容易就能判断问题出现在那个类的哪个方法了。 如果用第三方库编写自己的代码并准备将其在发布为程序库供他人开发应用程序所用那么尤其要注意重复符号问题。你的程序库所包含的那个第三方库也许还会为应用程序本身所引入。这时应该给你所用的那一份第三方库代码都加上你自己的前缀。 要点 选择与你的公司、应用程序或二者皆有关联之名称作为类名的前缀并在所有代码中均使用这一前缀。若自己所开发的程序库中用到了第三方库则应为其中的名称加上前缀。 第16条提供“全能初始化方法” 所有对象均要初始化。以iOS的UI框架UIKit为例其中有个类叫做UITableViewCell初始化该类对象时需要指明其样式及标识符标识符能够区分不同类型的单元格。我们把这种可为对象提供必要信息以便其能完成工作的初始化方法叫做“全能初始化方法”。 如果创建类实例的方法不止一种那么这个类就会有多个初始化方法。这当然很好不过仍然要在其中选定一个作为全能初始化方法令其他初始化方法都来调用它。NSDate就是个例子其初始化方法如下 - (id)init - (id)initWithString: (NSString *)string - (id)initWithTimeIntervalSinceNow: (NSTimeInterval)seconds - (id)initWithTimeInterval: (NSTimeInterval)seconds sinceDate: (NSDate *)refDate - (id)initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds - (id)initWithTimeIntervalSince1970: (NSTimeInterval)seconds在上面几个初始化方法中“initWithTimeIntervalSinceReferenceDate:”是全能初始化方法。也就是说其余的初始化方法都要调用它。于是只有在全能初始化方法中才会存储内部数据。而当底层数据存储机制改变时只需修改此方法的代码就好就无须改动其他初始化方法。 比如说我们要编写一个表示矩形的类。其接口可以这样写 #import Foundation/Foundation.hinterface EOCRectangle : NSObject property (nonatomic, assign, readonly) float width; property (nonatomic, assign, readonly) float height; end我们把属性声明为只读。不过这样一来外界就无法设置Rectangle对象的属性了。开发者可能会提供初始化方法以设置这两个属性 - (id)initWithWidth:(float)width andHeight:(float)height {if ((self [super init])) {_width width;_height height;}return self; }那如果我们用[[EOCRectangle alloc] init]来创建矩形会如何呢这么做时合乎规则的因为EOCRectangle的超类NSObject实现了这个名为init的方法调用完该方法后全部实例变量都将设为0。 如果我们想要用该方法初始化之后的矩形是一个默认的宽度与高度值或是抛出异常指明本类实例必须用“全能初始化方法”来初始化。我们要重新覆写init方法 //Using default values - (id)init {return [self initWithWidth:5.0 fandHeight:10.0f]; }//Throwing an exception - (id)init {throw [NSException exceptionWithName:NSInternalInconsistencyException reason:Must use initWithWidth:andHeight: instead. userInfo:nil]; }我们设置默认值的那个init方法调用了全能初始化方法 然后我们现在创建一个EOCSquare类本类表示正方形令其成为EOCRectangle的子类。新类的初始化方法应该如下编写 #import EOCRectangle.hinterface EOCSquare : EOCRectangle - (id)initWithDimension:(float)dimension; endimplementation EOCSquare- (id)initWithDimension:(float)dimension {return [super initWithWidth:dimension andHeight:dimension] }end上述方法就是EOCSquare类的全能初始化方法而且它调用了超类的全能初始化方法。回过头看看EOCRectangle类的实现代码你就会发现那个类也调用了其超类的全能初始化方法。全能初始化方法的调用链一定要维系。然而调用者可能会使用init方法或initWithWidth: andHeight:方法来初始化EOCSquare对象这样子会创建出宽高不一致的正方形。 于是就产生了一个问题如果子类的全能初始化方法与超类方法的名称不同那么总应覆写超类的全能初始化方法并在该方法调用该类的全能初始化方法。 在上方的例子中就应该像下面这样覆写EOCRectangle的全能初始化方法 - (id) initWithWidth: (float)width andHeight: (float)height {float dimension MAX(width, height);return [self initWithDimension:dimension]; }覆写了这个方法后即便使用init来初始化EOCSquare对象也能照常工作。原因在于EOCRectangle类覆写了init方法并以默认值为参数调用了该类的全能初始化方法。 有时候我们不想覆写超类的全能初始化方法常用的办法是覆写超类的全能初始化方法并于其中抛出异常 - (id) initWithWidth:(float)width andHeight:(float)height {throw [NSException exceptionWithName:NSInternalInconsistancyException reason:Must use initWithDimension: instead. userInfo:nil]; }这时候在EOCRectangle与EOCSquare这个例子中调用init方法也会抛出异常因为init方法也得调用“initWithWidth:andHeight:”。此时可以覆写init方法并在其中以合理的默认值来调用initWithDimension:方法 - (id) init {return [self initWithDimension:5.0f]; }有时候可能需要编写多个全能初始化方法。比如说如果某对象的实例有两种完全不同的创建方法必须分开处理。以NSCoding 协议为例此协议提供了“序列化机制”对象可依此指明其自身的编码及解码方式。NSCoding协议定义了下面这个初始化方法遵从该协议者都应实现此方法 - (id) initWithCoder:(NSCoder *)decoder;我们在实现此方法时一般不调用平常所使用的那个全能初始化方法因为该方法要通过“解码器”将对象数据解压缩所以和普通的初始化方法不同。而且如果超类也实现了NSCoding那么还需要调用超类的initWithCoder:方法。于是子类中有不止一个初始化方法调用了超类的初始化方法因此严格的说在这种情况下出现了两个全能初始化方法。 #import Foundation/Foundation.hinterface EOCRectangle : NSObjectNSCodingproperty (nonatomic, assign, readonly) float width; property (nonatomic, assign, readonly) float height;- (id)initWithWidth:(float)width andHeight:(float)height; endimplementation EOCRectangle//Designated initializer - (id)initWithWidth:(float)width andHeight:(float)height {if ((self [super init])) {_width width;_height height;}return self; }//Superclasss designated initializer - (id)init {return [self initWithWidth:5.0f andHeight:10.0f]; }//Initializer from NSCoding - (id) initWithCoder:(NSCoder *)decoder {//Call through to supers designated initializerif ((self [super init])) {_width [decoder decodeFloatForKey:width];_height [decoder decodeFloatForKey:height];}return self; }endNSCoding协议的初始化方法没有调用本类的全能初始化方法而是调用了超类的相关方法。然而若超类也实现了NSCoding则需改为调用超类的initWithCoder.初始化方法例如在此情况下EOCSquare类就得这么写 #import EOCRectangle.hinterface EOCSquare : EOCRectangle - (id)initWithDimension:(float)dimension; endimplementation EOCSquare//Designated initializer - (id) initWithDimension:(float)dimension {return [super initWithWidth:dimension andHeight:dimension]; }//Superclass designated initializer - (id) initWithWidth:(float)width andHeight:(float)height {float dimension MAX(width, height);return [self initWithDimension:dimension]; }//NSCoding designated initialzer - (id) initWithCoder:(NSCoder *)decoder {if ((self [super initWithCoder:decoder])) {//EOCSquares specific initalizer}return self; }end每个子类的全能初始化方法都应该调用其超类的对应方法并逐层向上实现initWithCoder:时也要这样应该先调用超类的相关方法然后在执行与本类有关的任务。这样编写出来的EOCSquare 类就完全遵守NSCoding协议了。 要点 在类汇总给你提供一个全能初始化方法并与文档里指明。其他初始化方法均应调用此方法。若全能初始化方法与超类不同则需覆写超类中的对应方法。如果超类的初始化方法不适用于子类那么应该覆写这个超类方法并在其中抛出异常。 第17条实现description方法 调试程序时需要打印并查看对象信息。一种办法是编写代码把对象的全部属性都输出到日志中。不过最常见的做法还是像下面这样 NSLog(object %, object);在构建需要打印到日志的字符串时object对象会收到description消息该方法所返回的描述信息将取代“格式字符串”里的%。比方说object是个数组若用下列代码打印其信息 NSArray *object [A string, (123)]; NSLog(object %, object);则会输出 object {A string123 }然而在自定义的类上这么做那么输出的信息却是下面这样 object EOCPerson: 0x7fd9a1600600但是可以看到这种方法只是打印了类名和对象的内存地址。如果我们想要打印更多的信息。我们只需要覆写description 方法并将描述此对象的字符串返回即可否则打印信息时就会调用NSObject类所实现的默认方法。例如有下面这个 代表个人信息的类 #import Foundation/Foundation.hinterface EOCPerson : NSObject property (nonatomic, copy, readonly) NSString *firstName; property (nonatomic, copy, readonly) NSString *lastName;- (id)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName; endimplementation EOCPerson- (id)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName {if ((self [super init])) {_firstName [firstName copy];_lastName [lastName copy];}return self; } end该类的description方法通常可以这样实现 - (NSString *) description {return [NSString stringWithFormat:%: %p, \% %\, [self class], self, _firstName, _lastName]; }如果按照上方的代码的话那么EOCPerson对像的输出结果就会如下 EOCPerson *person [[EOCPerson alloc] initWithFirstName:Bob lastName:Smith]; NSLog(person %, person); //Output //person EOCPerson: 0x7fb249c030f0, Bob Smith有个简单的办法可以在description中输出很多互不相同的信息那就是借助NSDictioniary类的description方法。此方法输出的信息的格式如下 {key: value;foo: bar; }自定义的description方法中把待打印的信息放到字典里面然后将字典对象的description方法所输出的内容包含在字符串里并返回例如下面这个类表示某地点的名称和地理坐标纬度与经度 #import Foundation/Foundation.hinterface EOCLocation : NSObject property (nonatomic, copy, readonly) NSString *title; property (nonatomic, assign, readonly) float latitude; property (nonatomic, assign, readonly) float longitude; - (id)initWithTitle:(NSString *)title latitude:(float)latitude longitude:(float)longitude; endimiplementation EOCLocation - (id)initWithTitle:(NSString *) title latitude:(float) latitude longitude:(float)longitude {if ((self [super init])) {_title [title copy];_latitude latitude;_longitude longitude;}return self; }end如果这个类的的description方法能够打印出地名和经纬度就好了。所以我们就可以像下面这样编写description方法用NSDictionary来实现此功能 - (NSString *) description {return [NSString stringWithFormat:%: %p, %,[self class],self,{latitude:_title,latitude:(_latitude),longitude:(_longitude)}]; } 输出的信息格式为 location EOCLocation: 0x7f98f2e01d20, {latitude 51.506longitude 0;title London; }用NSDictionary来实现该功能可以令代码更容易维护如果以后还要向类中新增属性并且要在description方法中打印那么只需要修改字典内容即可 debugDescription一种描述方法和description差不多就是描述的位置不一样description是在函数调用类的时候触发方法才输出的而debugDescription是在控制台中使用命令打印该对象时才调用的。当然加断点查看时也可以看到debugDescription的描述。 如果你在description不想将一些内容输出的话你就可以将那些数据写在debugDescription中让程序员自己调试时可以方便的看到这些数据而description方法就输出你想要让用户看到的信息就行了。 要点 实现description方法返回一个有意义的字符串用以描述该实例若想在调试时打印出更详尽的对象描述信息则应实现debugDescription方法。 第18条尽量使用不可变对象 默认情况下属性是“既可读又可写的”这样创建出来的类都是可变的。但是在设计类的时候我们应充分运用属性来封装数据在使用属性时则可将器声明为“只读”。 一般情况下我们要建模的数据未必都需要改变。比如说我们从服务器中请求来的数据加载成UI显示在屏幕上这些数据一般都是不需要去改变的。因此我们尽量要减少对象中的可变内容。 具体到编程中则应该尽量把对外公布出来的属性设为只读而且只在确有必要时才将属性对外公布。 为了将某类做成不可变的类需要把所有属性都声明为readonly: 例如 #import Foundation/Foundation.h interface EOCPointOfInterest: NSObject property (nonatomic, copy,readonly) NSString *identifier; property (nonatomic, copy, readonly) NSString *title; property (nonatomic, assign, readonly) float latitude; property (nonatomic, assign, readonly) float longitude; end如果有人试着改变属性值那么编译的时候就会报错。对象汇总给你的属性值可以读出但是无法写入开发者在使用对象时就能肯定其底层数据不会改变。 既然这些属性都没有设置方法setter那为何还要指定内存管理语义呢如果不指定采用默认的语义也可以 property (nonatomic, readonly)NSString *identifier; property (nonatomic, readonly) NSString *title; property (nonatomic, readonly) float latitude; property (nonatomic, readonly) float longitude;我们还是应该在文档里指明实现所用的内存管理语义这样的话在以后想把它变为可读写的属性时就会简单一些。 有时候肯想修改封装在对象内部的数据但是却不想令这些数据被外人所改动。通常的做法就是在对象内部将readonly属性重新声明为readwrite。将属性重新声明为readwrite这一操作可于“分类”中完成在公共接口中声明的属性可于此处重新声明属性的其他特质必须保持不变就行而readonly可以扩展为readwrite。 例如上方的例子在其所声明类的分类中可以写成下方的样子 #importEOCPointOfInterest.h interface EOCPointOfInterest() property (nonatomic, copy, readwrite)NSString* identifier; property (nonatomic, copy,readwrite) NSString* title; property (nonatomic, assign, readwrite) float latitude; eproperty (nonatomic, assign, readwrite)float longitude; end implementation EOCPointOfInterestend现在只能于其属性所在类的实现代码内部设置这些属性了其实更准确的说在对象外部仍然能通过**“键值编码”KVC**技术设置这些属性值比如说可以像下面这样修改属性值 [pointOfInterest setValue:abc forKey:identifier];这样子可以改动属性值因为KVC会在类里查找“setIdentifier:”方法并借此修改此属性。即使没有于公共接口中公布此方法它也依然包含在类中。 要点 尽量创建不可变的对象若某属性进可于对象内部修改则在“分类”中将其由属性扩展为readwrite属性不要把可变的collection作为属性公开而应提供相关方法以此修改对象中的可变collection。 第19条使用清晰而协调的命名方式 一开始学习的人通常会觉得OC的语言很繁琐因为其语法结构使得代码读起来和句子一样。以下方代码为例 NSString *text The quick brown fox jumped over the lazy dog; NSString *newText [text stringByReplacingOccurrencesOfString:fox withString:cat];这个句子虽然繁长但是准确描述了开发者想做的事。 下面介绍一种命名方式 驼峰命名法 方法和变量名的首个单词的首个字母小写然后后面的每个单词的首字母大写。类名也用驼峰命名法另外类名一般还有三个前缀字母。 方法命名 给方法命名时的注意事项可总结成下面几条规则 如果方法的返回值是新创建的那么方法名的首个词应是返回值的类型除非前面还 有修饰语例如localizedString。应该把表示参数类型的名词放在参数前面。如果方法要在当前对象上执行操作那么就应该包含动词;若执行操作时还需要参数 则应该在动词后面加 上一个或多个名词。不要使用str 这种简称应该用string 这样的全称。Boolean 属性应加is 前缀。如果某方法返回非属性的Boolean 值那么应该根据其功 能选用has 或is 当前缀。将get 这个前缀留给那些借由“输出参数〞来保存返回值的方法比如说把返回值填充到〝C语言式数组” ( C - style array ) 里的那种方法就可以使用这个词做前缀 。 类和协议的命名 其中最重要的一点就是命名方式应该协调一致。如果要从其他框架中继承子类那么务必遵循其命名惯例。比方说要从UIView类中继承自定义的子类那么类名末尾的词必须是View。同理若要创建自定义的委托协议则其名称中应该包含委托发起方的名称后面再跟上Delegate一词。 要点 起名时应遵从标准的OC命名规范这样创建出来的接口更容易为开发者所理解。方法名要言简意赅从左至右读起来要像个日常用语中的句子才好。方法名里不要使用缩略后的类型名称。给方法名起名时的第一要务就是确保其风格与你自己的代码或所要集成的框架相符。 第20条为私有方法名加前缀 编写类的实现代码时经常需要写一些只在内部使用的方法。应该为这种方法的名称加上某些前缀这有助于调试因为据此很容易能把公共方法和私有方法区别开。 一般用p_作为前缀p表示“private”私有的下划线后面的部分按照常用的驼峰命名即可其首字母要小写。例如包含私有方法的EOCObject类可以这样写 - (void) p_privateMethod {/* ... */ }与公共方法不同私有方法不出现在接口定义中。有时可能要在“分类”里声明私有方法然而最近修订的编译器已经不要求在使用方法前必须先行声明了。所以说私有方法一般只在实现的时候声明。 苹果公司喜欢单用一个下划线做私有方法的前缀。所以开发者当避免这样使用前缀因为你有可能会无意间覆写父类的同名方法。 要点 给私有方法的名称加上前缀这样可以很容易地将其同公共方法区分开。不要单用一个下划线做私有方法的前缀我也这种做法是预留给苹果公司的。 第21条理解Objective-C错误模型 很多编程语言都有“异常”机制通过异常机制来处理错误当然OC中也有。 首先我们要注意的是“自动引用计数”在默认情况下不是“异常安全的”就是说如果抛出异常那么本应该在作用域末尾释放的对象现在却不会释放了这样就会造成内存泄漏问题如果想生成“异常安全”的代码可以通过设置编译器的标志来实现不过这将引入一些额外的代码在不抛出异常时也照样要执行这部分代码。需要打开的编译器标志叫做-fobjc-arc-exceptions。 OC语言现在所采用的办法是只在极其罕见的情况下抛出异常异常抛出之后无须考虑恢复问题而且应用程序此时也应该退出。这就是说不用再编写复杂的“异常安全”代码了。 异常只应该用于极其严重的错误比如说你编写了某个抽象基类它的正确用法是先从中继承一个子类然后使用这个子类。这种情况下如果有人直接使用了这个抽象类那么就可以考虑抛出异常 - (void) mustOverrideMethod {NSString *reason [NSString stringWithFormat: % must be oberridden, NSStringFormSelector(_cmd)];throw [NSException exceptionWithName:NSInterNalInconsistencyException reason:reason userInfo:nil]; }既然异常只用于处理严重错误那么对其他错误怎么办在出现“不那么严重的错误”时OC语言所用的编程范式为令方法返回nil/0或是使用NSError以表明其中有错误发生。 比如说如果初始化方法无法根据传入的参数来初始化当前实例那么就可以令其返回nil/0 - (id)initWithValue:(id)value {if ((self [super init])) {if (/* Value means instance cant bo created */) {self nil;} elsef {//Initialize instance}}return self; }这样一来如果if语句发现无法用传入的参数值来初始化当前实例就会把self设置成nil整个方法的返回值也就是nil了调用者发现初始化方法并没有把实例创建好于是便可确定其中发生了错误。 NSError的用法更加灵活我们可以经由此对象把导致错误的原因回报给调用者。NSError对象里封装了三条信息 Error domain(错误范围其类型为字符串) 错误发生的范围。也就是产生错误的根源通常用一个特有的全局变量来定义。比方说“处理URL的子系统”(URL-handling subsystem)在从URL中解析或取得数据时如果出错了那么就会使用NSURLErrorDomain来表示错误范围。Error code(错误码其类型为整数) 独有的错误代码用以指明在某个范围内具体发生了何种错误。某个特定范围内可能会发生一系列相关错误这些错误情况通常采用enum来定义。例如当HTTP请求出错时可能会把HTTP状态码设为错误码。User info(用户信息其类型为字典) 有关此错误的额外信息其中或许包含一段“本地化的描述”(localized description)或许还含有导致该错误发生的另外一个错误经由此种信息可将相关错误串成一条“错误链”(chain of errors)。 在设计API时NSError的第一种常见用法时通过委托协议来传递此错误。有错误发生时当前对象会把错误信息经由协议中的某个方法传给其委托对象。 NSError的另一种常见的用法是经由方法的“输出参数”返回给调用者。 就是说用一个方法来判断你传过去的error是否真的有错误返回Boolean值之后你就可以根据error是否有内容或者Boolean值来决定处理的代码和不处理的代码。就像这样 NSError error nil; BOOL ret [object doSomething:error]; if (error){ // There was an error }doSomething:会处理一些事并且还会将出错的问题返回给error指针传回给调用者并且还会返回一个Boolean值给ret。 NSError对象里的“错误范围”、“错误码”、“用户信息”等部分应该按照具体的错误情况填入适当的内容。这样的话调用者就可以根据错误的类型分别处理各种错误了。错误范围应该定义成NSString型的全局变量而错误码则定义成枚举类型为佳。 //EOCErrors.h extern NSString *const EOCErrorDomain;typedef NS_ENUM(NSUInterger, EOCError) {EOCErrorUnknown -1EOCErrorInternalInconsistency 100EOCErrorGeneralFault 105;EOCErrorBadInput 500; } //EOCErrors.m NSString *const EOCErrorDomain EOCErrorDomain;要点 只有发生了可使整个应用程序崩溃的严重错误时才应使用异常。在错误不那么严重的情况下可以指派“委托方法”来处理错误也可以把错误信息放在NSError对象里经由“输出参数”返回给调用者。 第22条理解NSCopying协议 我们经常会使用copy函数但是若是你自定义的类他自己就不会实现这个函数此时就需要你自己来实现了要实现copy函数就的实现NSCopying协议该协议只有一个方法 - (id)copyWithZone:(NSZone *)zone;copy方法由NSObject实现该方法只是以“默认区”为参数来调用“copyWithZone:”。所以要实现copy函数他才是关键。 想要重写copy函数要声明该类遵从NSCopying协议并实现其中的方法 #import Foundation/Foundation.h interface EOCPerson : NSObject NSCopying property (nonatomic, copy, readonly) NSString *firstName; property (nonatomic, copy, readonly) NSString *lastName; - (id) initwithFirstName: (NSString*)firstName andLastName: (NSString*) lastName; end实现协议中规定的方法 - (id) copyWithZone: (NSZone*)zone {EOCPerson *copy [[[self class] allocWithZone: zone] initwithFirstName: firstName andLastName: lastName];return copy; }mutableCopy方法此方法来自另一个叫做NSMutableCopying的协议。该协议与NSCopying类似也只定义了一个方法然而方法名不同 (id)mutableCopyWithZone:(NSZone*)zone在编写拷贝方法时还要决定一个问题就是应该执行“深拷贝”(deep copy)还是“浅拷贝”(shallow copy)。深拷贝的意思就是在拷贝对象自身时将其底层数据也一并复制过去。Foundation框架中的所有collection类在默认情况下都执行浅拷贝也就是说只拷贝容器对象本身而不复制其中数据。这样做的主要原因在于容器内的对象未必都能拷贝而且调用者也未必想在拷贝容器时一并拷贝其中的每个对象。 图3-2描述了深拷贝与浅拷贝的区别 一般情况下在自定义的类中以浅拷贝的方式实“copyWithZone:”方法。但如果有必要的话也可以增加一个执行深拷贝的方法。以NSSet为例该类提供了下面这个初始化方法用以执行深拷贝 -(id) deepCopy { EOCPerson *copy [[[self class] alloc]initWithFirstName:_firstNameandLastName_lastName];copy-_friends[[NSMutableSet alloc] initWithSet:_friendscopyItems:YES]return copy; }-(id) initWithSet:(NSArray*)array copyItems:(BOOL) copyItems若copyItem参数设为 YES则该方法会向数组中的每个元素发送copy消息用拷贝好的元素创建新的set并将其返回给调用者。 要点 若想令自己所写的对象具有拷贝功能则需实现NSCopying协议。如果自定义的对象分为可变版本和不可变版本那么就要同时实现NSCopying与NSMutableCopying协议。复制对象时需决定采用浅拷贝还是深拷贝一般情况下应该尽量执行浅拷贝。如果你所写的对象需要深拷贝那么可考虑新增一个专门执行深拷贝的方法。
http://www.hkea.cn/news/14273848/

相关文章:

  • 打开一个网站搜索页面跳转js保险平台
  • 网站建设公司是什么wordpress 技术教程
  • 手机怎么制作钓鱼网站wordpress 删除模板
  • wdcp搭建网站教程2003网站服务器建设中
  • 怎么编程一个网站建设直播网站需要多少钱
  • 网站qq访客 原理常州网站建设 个人
  • 商洛网站开发建设工程安全备案网站
  • 代加工接订单网站专业网站建设设计装饰
  • 益阳网站建设广告半成品网站
  • 二手书网站策划书怎么看公司是不是外包
  • 建个人网站怎么赚钱太平洋建设 网站
  • 网站建设验收方发言稿注册一个公司需要几个人
  • 我是做颗粒在什么网站上怎么看一级还是二级域名
  • 枣庄专业三合一网站开发小程序制作pdf
  • 官网和门户网站的区别wordpress登录更改域名后
  • 公司网站怎么做实名认证dedecms 关闭网站
  • 网站建设 pdf宣传片制作公司费用
  • jsp网站开发答辩wordpress滑块验证码
  • 网站建设项目单子来源西安高端网站
  • 网站优化是往新闻中心发新闻吗宁波高端定制网站建设
  • 网站打开速度突然变慢的原因网络文化经营许可证要多少钱
  • 用eclipse做网站诸葛企业网站建设公司
  • 廊坊企业自助建站聚美优品网站建设情况
  • 网站开发网络公杭州h5建站
  • 厦门手机网站泉州建站费用
  • 张家港质监站网址网站域名要钱吗
  • 设计网站软件开发大连比较好的网站公司吗
  • 建设一个视频网站首页西安建站模板厂家
  • 松江建设投资有限公司网站学校后勤网站建设方案
  • 如何进行网站的seo百度产品推广