Objective c 命名方法的简单规则,与ARC命名约定兼容
我很难理解ARC的命名约定。我一直用ARC编码,我想这就是原因 1.类方法Objective c 命名方法的简单规则,与ARC命名约定兼容,objective-c,memory-leaks,automatic-ref-counting,naming-conventions,class-method,Objective C,Memory Leaks,Automatic Ref Counting,Naming Conventions,Class Method,我很难理解ARC的命名约定。我一直用ARC编码,我想这就是原因 1.类方法 我应该为以下方法选择什么名称 关于内存管理,这两个名称之间有什么区别 姓名: + (MyObject *)newObjectFrom:(MyObject *)anObject withOptions:(NSDictionary*)options { MyObject * newObject = [anObject copy] ; [newObject modifyWi
- 我应该为以下方法选择什么名称
- 关于内存管理,这两个名称之间有什么区别
+ (MyObject *)newObjectFrom:(MyObject *)anObject
withOptions:(NSDictionary*)options
{
MyObject * newObject = [anObject copy] ;
[newObject modifyWith:options] ;
return newObject ;
}
- (MyObject *)newObjectwithOptions:(NSDictionary*)options
{
MyObject * newObject = [self copy] ;
[newObject modifyWith:options] ;
return newObject ;
}
还是这个名字
+ (MyObject *)objectFrom:(MyObject *)anObject
withOptions:(NSDictionary*)options
{
MyObject * newObject = [anObject copy] ;
[newObject modifyWith:options] ;
return newObject ;
}
2.实例方法
- 我应该为以下方法选择什么名称
- 关于内存管理,这两个名称之间有什么区别
+ (MyObject *)newObjectFrom:(MyObject *)anObject
withOptions:(NSDictionary*)options
{
MyObject * newObject = [anObject copy] ;
[newObject modifyWith:options] ;
return newObject ;
}
- (MyObject *)newObjectwithOptions:(NSDictionary*)options
{
MyObject * newObject = [self copy] ;
[newObject modifyWith:options] ;
return newObject ;
}
还是这个名字
- (MyObject *)objectwithOptions:(NSDictionary*)options
{
MyObject * newObject = [self copy] ;
[newObject modifyWith:options] ;
return newObject ;
}
2.命名方法的简单规则
命名方法时有没有一个简单的基本规则可以遵循?
我说的“基本,简单”,是指
- 类似于“
当对象属于该类时”,“strong
当该对象仅由该类引用,并且(因此)由另一类拥有时”的规则弱
- (和/或)不涉及无
的内存管理的规则ARC
- (和/或)不使用“自动释放”、“释放”等词语的规则
new
在Objective-C中非常少见,因此最好使用objectFrom:
更好的方法是更精确地描述您正在创建的对象的类型。例如:
[NSArray arrayWithArray:]
[NSString stringWithFormat:]
或者在您创建副本的情况下,假设您正在创建“客户端”对象:
其中,实际上不需要使用
对于2,我会选择:
copyWithOptions:
当您或多或少地定制[NSObject copy]
时。我还将只实现这个方法,并删除现在多余的1,因为更少的方法更清晰、更易于记录和维护
如果有疑问,只需搜索SDK文档,查看苹果如何命名类似的方法
编辑:
在第一段中,我的意思不是鼓励不好的命名实践,只是说它们不是内存管理问题的原因。然而,您应该尝试遵循其他答案中指出的命名约定,或者正如我所说的,“像苹果那样做”。方法名称非常重要。ARC如何解释方法名称的官方文档可以在上一节的clang ARC文档中找到。我在苹果世界的经验是,像您的示例那样的工厂方法通常包括按惯例“创建”。这在ARC中可能不那么重要了,但在过去,在方法或函数签名中“创建”是一种非常可靠的方法,可以确保您理解您是在获得结果对象的所有权(由于其上有一个release/free()),而不是假定为自动释放[NSArray array]、[uicolorWith..的实例类型等等,所以我仍然非常喜欢遵循这个惯例。当Rivera说方法名称不重要时,他可能遵循了他的经验:它总是有效的。这是正确的。您可能不理解方法名的作用,这是正确的,因为您一直使用ARC。那有什么大不了的 我在这个答案的末尾添加了一个概要来说明MRR的问题。正如您在这里看到的,您不必像使用MRR那样关心使用ARC的命名规则 为了给您提供更详细的解释,您必须了解使用MRR会发生什么: 在ARC之前,必须手动进行内存管理。这样他就必须知道,回报值是什么样的所有权。长话短说,必须知道是否必须释放返回的对象: 规则1:您不拥有由方法自动返回的对象。如果你想拿着它,当你用完它的时候,保留它并释放它
id object = [[object methodThatReturnsAnObject] retain]; // I want to hold it
…
[object release]; // Done with it
id object = [object methodThatReturnsAnObject]; // I do not want to hold it
…
// I do not release it
做一个深入的分析,你会发现有时会有问题。(对象释放作为副作用。)但这是基本方法
这样做的好处是可以在本地(在复合语句中)处理retain-release对,并且很容易跟踪对象的所有权
规则2:但是当第一次创建对象时,这无法工作:消息的发送者总是持有它。否则它将被立即销毁(=在发送者有机会保留它之前)。因此有一个附加规则:
如果返回对象的类方法的名称以alloc、init或new开头,则必须像处理retain一样处理返回的对象。或者一句话:所有权转让:
id object = [Class allocOrInitOrNewMethod];
…
[object release];
当-retain
明确取得所有权时,alloc–
,init…
,new…
隐式转移所有权
所有其他方法的行为与规则1类似
规则3:有时你需要一个自动释放池。
要使ARP的优势变得明显,请考虑以下代码:(它是无用的,只是为了演示问题
案例1.1:
Person *person = [[Person alloc] initWithName:…]; // Ownership transfer, release person, when you are done
NSString *name = [person name]; // the name object is hold by the person object only
[person release]; // I do not need the person object any more
[name doSomething]; // Crash: The person was the only object holding the name
另一个问题:
案例2.1:
Person *person = [[Person alloc] initWithName:…]; // Ownership transfer, release person, when you are done
if (…)
{
return; // break, continue, goto
}
…
[person release];
由于从未到达最后一行,因此对象从未释放
您可以使用自动释放方法修复该问题。只要控制流返回到运行循环,移动到ARP的对象就会存在。因此,它通过每个方法、通过方法返回等方式存在。要显式执行此操作,请执行以下操作:
案例1.2:
Person *person = [[[Person alloc] initWithName:…] autorelease]; // No ownership transfer, persons belongs to the ARP
NSString *name = [person name]; // the name object is hold by the person object only
[name doSomething]; // No Crash: The person object holding the name object is still alive
案例2.2:
Person *person = [[[Person alloc] initWithName:…] autorelease]; // No ownership transfer, prsons belongs to the AR.
if (…)
{
return; // break, continue, goto
}
…
// No release necessary.
因为人们不得不懒得键入这么长的消息链,所以方便性是有限的
Person *person = [personWithName:…]; // No ownership transfer, persons belongs to the AR.
if (…)
{
return; // break, continue, goto
}
…
// No release necessary.
- (NSString*)name
{
return [[_name retain] autorelease];
}
// MRR:
Person *person = [[Person alloc] initWithName:@"Amin"];
…
[person release]; // You create it, you release it
// ARC:
Person *person = [[Person alloc] initWithName:@"Amin"];
…
// MRR:
Person *person = [[Person newPersonWithName:@"Amin"];
…
[person release]; // You create it, you release it
// ARC:
Person *person = [[Person newPersonWithName:@"Amin"];
…
// MRR:
Person *person = [[Person personWithName:@"Amin"]; // Autoreleased
…
// ARC:
Person *person = [[Person personWithName:@"Amin"];
…
// MRR
+ (Person*)newPersonWithName:(NSString*)name
{
return [[self alloc] initWithName:name];
}
// ARC
+ (Person*)newPersonWithName:(NSString*)name
{
return [[self alloc] initWithName:name];
}
// MRR
+ (Person*)personWithName:(NSString*)name
{
return [[[self alloc] initWithName:name] autorelease];
}
// ARC
+ (Person*)personWithName:(NSString*)name
{
return [[self alloc] initWithName:name];
}