Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
滥用Objective-C速记符号_Objective C - Fatal编程技术网

滥用Objective-C速记符号

滥用Objective-C速记符号,objective-c,Objective C,除了让老式的Objective-C程序员心脏病发作外,这样做是否还有其他性能影响: NSMutableArray *derp = @[].mutableCopy 与此相比: NSMutableArray *derp = [[NSMutableArray alloc] init]; 是的,一个是分配两个对象,另一个不是。我不知道[NSMutableArray new] 更新:格雷格·帕克是对的,他们都只分配一个对象 很难说到底创建了多少对象,尤其是在数组文本的情况下 假设@[]扩展到数组wit

除了让老式的Objective-C程序员心脏病发作外,这样做是否还有其他性能影响:

NSMutableArray *derp = @[].mutableCopy
与此相比:

NSMutableArray *derp = [[NSMutableArray alloc] init];

是的,一个是分配两个对象,另一个不是。我不知道
[NSMutableArray new]


更新:格雷格·帕克是对的,他们都只分配一个对象

很难说到底创建了多少对象,尤其是在数组文本的情况下

假设
@[]
扩展到
数组with objects:count:
,我怀疑它实现为
[[self alloc]initWithObjects:objects count:count]autorelease]

因此,可能会在该点分配第二个对象,因为
NSArray
是一个,并且
-[NSArray init]
的实现可能类似于以下内容:

- (id)init
{
    [self release];
    self = [[__NSArrayI alloc] init];
    return self;
}
为了证实我的怀疑,我编写了一个小程序,在不同阶段打印各种类型的
NSArray
对象类注意,为了真正确定,有必要捕获
NSArray
的所有分配和初始化方法,直到我们这样做,我们只能推测。但无论如何,代码如下:

#import <Foundation/Foundation.h>


int main()
{
    NSArray *a = [NSArray alloc];
    NSLog(@"NSArray before init: %@", a.class);

    a = [a init];
    NSLog(@"NSArray after init: %@", a.class);

    NSArray *al = @[];
    NSLog(@"Array literal: %@", al.class);

    NSMutableArray *ma1 = [a mutableCopy];
    NSLog(@"NSMutableArray (copied): %@", ma1.class);

    NSMutableArray *ma2 = [NSMutableArray alloc];
    NSLog(@"NSMutableArray (manufactured) before init: %@", ma2.class);

    ma2 = [ma2 init];
    NSLog(@"NSMutableArray (manufactured) after init: %@", ma2.class);

    return 0;
}
编辑:这里还有一些关于挂钩的代码。结果非常有趣,但这会打印大量文本,因此鼓励您编译并运行它。结果是,基本上,初始化者不直接通过
[NSArray init]

#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/message.h>

void hook(Class cls, SEL sel, IMP newimp, IMP *old)
{
    Method m = class_getInstanceMethod(cls, sel);
    *old = method_setImplementation(m, newimp);
}

#define CLS(c) objc_getClass(#c)
#define META(c) objc_getMetaClass(#c)

IMP old_$_NSArray_$_alloc;
IMP old_$_NSMutableArray_$_alloc;
IMP old_$_NSPlaceholderArray_$_alloc;
IMP old_$_NSArrayI_$_alloc;
IMP old_$_NSArrayM_$_alloc;

IMP old_$_NSArray_$_init;
IMP old_$_NSMutableArray_$_init;
IMP old_$_NSPlaceholderArray_$_init;
IMP old_$_NSArrayI_$_init;
IMP old_$_NSArrayM_$_init;

id new_$_NSArray_$_alloc(id self, SEL _cmd)
{
    printf("+ [NSArray<%p> alloc]\n", self);
    return old_$_NSArray_$_alloc(self, _cmd);
}

id new_$_NSMutableArray_$_alloc(id self, SEL _cmd)
{
    printf("+ [NSMutableArray<%p> alloc]\n", self);
    return old_$_NSMutableArray_$_alloc(self, _cmd);
}

id new_$_NSPlaceholderArray_$_alloc(id self, SEL _cmd)
{
    printf("+ [NSPlaceholderArray<%p> alloc]\n", self);
    return old_$_NSPlaceholderArray_$_alloc(self, _cmd);
}

id new_$_NSArrayI_$_alloc(id self, SEL _cmd)
{
    printf("+ [NSArrayI<%p> alloc]\n", self);
    return old_$_NSArrayI_$_alloc(self, _cmd);
}

id new_$_NSArrayM_$_alloc(id self, SEL _cmd)
{
    printf("+ [NSArrayM<%p> alloc]\n", self);
    return old_$_NSArrayM_$_alloc(self, _cmd);
}

id new_$_NSArray_$_init(id self, SEL _cmd)
{
    printf("- [NSArray<%p> init]\n", self);
    return old_$_NSArray_$_init(self, _cmd);
}

id new_$_NSMutableArray_$_init(id self, SEL _cmd)
{
    printf("- [NSMutableArray<%p> init]\n", self);
    return old_$_NSMutableArray_$_init(self, _cmd);
}

id new_$_NSPlaceholderArray_$_init(id self, SEL _cmd)
{
    printf("- [NSPlaceholderArray<%p> init]\n", self);
    return old_$_NSPlaceholderArray_$_init(self, _cmd);
}

id new_$_NSArrayI_$_init(id self, SEL _cmd)
{
    printf("- [NSArrayI<%p> init]\n", self);
    return old_$_NSArrayI_$_init(self, _cmd);
}

id new_$_NSArrayM_$_init(id self, SEL _cmd)
{
    printf("- [NSArrayM<%p> init]\n", self);
    return old_$_NSArrayM_$_init(self, _cmd);
}

int main()
{
    hook(META(NSArray), @selector(alloc), (IMP)new_$_NSArray_$_alloc, &old_$_NSArray_$_alloc);
    hook(META(NSMutableArray), @selector(alloc), (IMP)new_$_NSMutableArray_$_alloc, &old_$_NSMutableArray_$_alloc);
    hook(META(__NSPlaceholderArray), @selector(alloc), (IMP)new_$_NSPlaceholderArray_$_alloc, &old_$_NSPlaceholderArray_$_alloc);
    hook(META(__NSArrayI), @selector(alloc), (IMP)new_$_NSArrayI_$_alloc, &old_$_NSArrayI_$_alloc);
    hook(META(__NSArrayM), @selector(alloc), (IMP)new_$_NSArrayM_$_alloc, &old_$_NSArrayM_$_alloc);

    hook(CLS(NSArray), @selector(init), (IMP)new_$_NSArray_$_init, &old_$_NSArray_$_init);
    hook(CLS(NSMutableArray), @selector(init), (IMP)new_$_NSMutableArray_$_init, &old_$_NSMutableArray_$_init);
    hook(CLS(NSPlaceholderArray), @selector(init), (IMP)new_$_NSPlaceholderArray_$_init, &old_$_NSPlaceholderArray_$_init);
    hook(CLS(NSArrayI), @selector(init), (IMP)new_$_NSArrayI_$_init, &old_$_NSArrayI_$_init);
    hook(CLS(NSArrayM), @selector(init), (IMP)new_$_NSArrayM_$_init, &old_$_NSArrayM_$_init);


    NSArray *a = [NSArray alloc];
    NSLog(@"NSArray before init: %@<%p>", a.class, a);

    a = [a init];
    NSLog(@"NSArray after init: %@<%p>", a.class, a);

    NSArray *al = @[];
    NSLog(@"Array literal: %@<%p>", al.class, al);

    NSMutableArray *ma1 = [a mutableCopy];
    NSLog(@"NSMutableArray (copied): %@<%p>", ma1.class, ma1);

    NSMutableArray *ma2 = [NSMutableArray alloc];
    NSLog(@"NSMutableArray (manufactured) before init: %@<%p>", ma2.class, ma2);

    ma2 = [ma2 init];
    NSLog(@"NSMutableArray (manufactured) after init: %@<%p>", ma2.class, ma2);

    return 0;
}
#导入
#进口
#进口
无效挂钩(类别cls、SEL-SEL、IMP新IMP、IMP*旧)
{
方法m=类_getInstanceMethod(cls,sel);
*old=方法(m,newimp);
}
#定义CLS(c)objc_getClass(#c)
#定义元(c)objc_getMetaClass(#c)
IMP old$\u NSArray$\u alloc;
IMP old_$\u NSMutableArray_$\u alloc;
进口旧货仓;
IMP old$\u NSArrayI$\u alloc;
IMP old$\u NSArrayM$\u alloc;
IMP old$\u NSArray$\u init;
IMP old_$\u NSMutableArray_$\u init;
IMP old_$\u NSPlaceholderArray_$\u init;
IMP old$\u NSArrayI$\u init;
IMP old$\u NSArrayM$\u init;
id新建\u$\ u NSArray\u$\ u alloc(id自身,SEL\u cmd)
{
printf(“+[NSArray alloc]\n”,self);
返回旧的数组alloc(self,cmd);
}
id new\u$\ u NSMutableArray\u$\ u alloc(id self,SEL\u cmd)
{
printf(“+[NSMutableArray alloc]\n”,self);
返回旧的数组(self,cmd);
}
id new\u$\ u NSPlaceholderArray\u$\ u alloc(id self,SEL\u cmd)
{
printf(“+[NSPlaceholderArray alloc]\n”,self);
返回旧的$\u NSPlaceholderArray$\u alloc(self,\u cmd);
}
id new_$\u NSArrayI_$\u alloc(id self,SEL\u cmd)
{
printf(“+[NSArrayI alloc]\n”,self);
返回旧的$\u NSArrayI$\u alloc(self,\u cmd);
}
id new_$\u NSArrayM_$\u alloc(id self,SEL\u cmd)
{
printf(“+[NSArrayM alloc]\n”,self);
返回旧的$\u NSArrayM$\u alloc(self,\u cmd);
}
id new\u$\ u NSArray\u$\ u init(id self,SEL\u cmd)
{
printf(“-[NSArray init]\n”,self);
返回旧的数组初始化(self,cmd);
}
id new\u$\ u NSMutableArray\u$\ u init(id self,SEL\u cmd)
{
printf(“-[NSMutableArray init]\n”,self);
返回旧的数组init(self,_cmd);
}
id new\u$\ n位置保持阵列\u$\ u初始化(id self,SEL\u cmd)
{
printf(“-[NSPlaceholderArray init]\n”,self);
返回旧的$\u NSPlaceholderArray$\u init(self,\u cmd);
}
id new\u$\ u NSArrayI\u$\ u init(id self,SEL\u cmd)
{
printf(“-[NSArrayI init]\n”,self);
返回旧的$\u NSArrayI$\u init(self,\u cmd);
}
id new\u$\ u NSArrayM\u$\ u init(id self,SEL\u cmd)
{
printf(“-[NSArrayM init]\n”,self);
返回旧的$\u NSArrayM$\u init(self,\u cmd);
}
int main()
{
钩子(META(NSArray),@selector(alloc),(IMP)new_$\u NSArray\u$\ u alloc和old_$\u NSArray\u$\ u alloc);
钩子(META(NSMutableArray),@selector(alloc),(IMP)new_$\u NSMutableArray_$\u alloc和old_$\u NSMutableArray_$\u alloc);
钩子(元(uuu NSPlaceholderArray),@selector(alloc),(IMP)new$u NSPlaceholderArray$u alloc和old$u NSPlaceholderArray$oc);
钩子(META(uu NSArrayI),@selector(alloc),(IMP)new$u NSArrayI$u alloc和old$u NSArrayI$u alloc);
钩子(META(uu NSArrayM),@selector(alloc),(IMP)new$u NSArrayM u alloc和old$u NSArrayM u alloc);
钩子(CLS(NSArray),@selector(init),(IMP)new_$\u NSArray\u$\ u init和old_$\u NSArray\u$\ u init);
钩子(CLS(NSMutableArray),@selector(init),(IMP)new_$\u NSMutableArray_$\u init和old_$\u NSMutableArray_$\u init);
钩子(CLS(NSPlaceholderArray)、@selector(init)、(IMP)新的$\u NSPlaceholderArray$\u init和旧的$\u NSPlaceholderArray$\u init);
钩子(CLS(NSArrayI),@selector(init),(IMP)new$\u NSArrayI$\u init和old$\u NSArrayI$\u init);
钩子(CLS(NSArrayM),@selector(init),(IMP)new_$\u NSArrayM_$\u init和old_$\u NSArrayM_$\u init);
NSArray*a=[NSArray alloc];
NSLog(@“初始化前的NSArray:%@”,a.class,a);
a=[a初始值];
NSLog(@“初始化后的NSArray:%@”,a.class,a);
NSArray*al=@[];
NSLog(@“数组文字:%@”,al.class,al);
NSMutableArray*ma1=[a mutableCopy];
NSLog(@“NSMutableArray(已复制):%@”,ma1.class,ma1);
NSMUTABLEARRY*ma2=[NSMUTABLEARRY alloc];
NSLog(@“初始化前的NSMutableArray(已制造):%@”,ma2.class,ma2);
ma2=[ma2初始];
NSLog(@“NSMUTABLEARRY(制造)在初始化之后:%@”,ma2.class,ma2);
返回0;
}

我将给出与下面不同的答案

除非你测量了你的应用程序的性能,发现它缺乏,并且在代码的这一部分发现它缺乏正确的地方,否则你是在为错误的事情进行优化。(如果你做到了这一点,你可以很容易地衡量哪一个更快。)

您应该优化代码的清晰度、编写速度和正确性

在这方面,我倾向于使用第二个代码段而不是第一个。它说的和你想做的差不多。第一个片段不仅更难阅读;它还提交了使用点表示法调用方法而不是获取属性值的样式错误

再加上引发心脏病发作并不好。:)

班级俱乐部
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/message.h>

void hook(Class cls, SEL sel, IMP newimp, IMP *old)
{
    Method m = class_getInstanceMethod(cls, sel);
    *old = method_setImplementation(m, newimp);
}

#define CLS(c) objc_getClass(#c)
#define META(c) objc_getMetaClass(#c)

IMP old_$_NSArray_$_alloc;
IMP old_$_NSMutableArray_$_alloc;
IMP old_$_NSPlaceholderArray_$_alloc;
IMP old_$_NSArrayI_$_alloc;
IMP old_$_NSArrayM_$_alloc;

IMP old_$_NSArray_$_init;
IMP old_$_NSMutableArray_$_init;
IMP old_$_NSPlaceholderArray_$_init;
IMP old_$_NSArrayI_$_init;
IMP old_$_NSArrayM_$_init;

id new_$_NSArray_$_alloc(id self, SEL _cmd)
{
    printf("+ [NSArray<%p> alloc]\n", self);
    return old_$_NSArray_$_alloc(self, _cmd);
}

id new_$_NSMutableArray_$_alloc(id self, SEL _cmd)
{
    printf("+ [NSMutableArray<%p> alloc]\n", self);
    return old_$_NSMutableArray_$_alloc(self, _cmd);
}

id new_$_NSPlaceholderArray_$_alloc(id self, SEL _cmd)
{
    printf("+ [NSPlaceholderArray<%p> alloc]\n", self);
    return old_$_NSPlaceholderArray_$_alloc(self, _cmd);
}

id new_$_NSArrayI_$_alloc(id self, SEL _cmd)
{
    printf("+ [NSArrayI<%p> alloc]\n", self);
    return old_$_NSArrayI_$_alloc(self, _cmd);
}

id new_$_NSArrayM_$_alloc(id self, SEL _cmd)
{
    printf("+ [NSArrayM<%p> alloc]\n", self);
    return old_$_NSArrayM_$_alloc(self, _cmd);
}

id new_$_NSArray_$_init(id self, SEL _cmd)
{
    printf("- [NSArray<%p> init]\n", self);
    return old_$_NSArray_$_init(self, _cmd);
}

id new_$_NSMutableArray_$_init(id self, SEL _cmd)
{
    printf("- [NSMutableArray<%p> init]\n", self);
    return old_$_NSMutableArray_$_init(self, _cmd);
}

id new_$_NSPlaceholderArray_$_init(id self, SEL _cmd)
{
    printf("- [NSPlaceholderArray<%p> init]\n", self);
    return old_$_NSPlaceholderArray_$_init(self, _cmd);
}

id new_$_NSArrayI_$_init(id self, SEL _cmd)
{
    printf("- [NSArrayI<%p> init]\n", self);
    return old_$_NSArrayI_$_init(self, _cmd);
}

id new_$_NSArrayM_$_init(id self, SEL _cmd)
{
    printf("- [NSArrayM<%p> init]\n", self);
    return old_$_NSArrayM_$_init(self, _cmd);
}

int main()
{
    hook(META(NSArray), @selector(alloc), (IMP)new_$_NSArray_$_alloc, &old_$_NSArray_$_alloc);
    hook(META(NSMutableArray), @selector(alloc), (IMP)new_$_NSMutableArray_$_alloc, &old_$_NSMutableArray_$_alloc);
    hook(META(__NSPlaceholderArray), @selector(alloc), (IMP)new_$_NSPlaceholderArray_$_alloc, &old_$_NSPlaceholderArray_$_alloc);
    hook(META(__NSArrayI), @selector(alloc), (IMP)new_$_NSArrayI_$_alloc, &old_$_NSArrayI_$_alloc);
    hook(META(__NSArrayM), @selector(alloc), (IMP)new_$_NSArrayM_$_alloc, &old_$_NSArrayM_$_alloc);

    hook(CLS(NSArray), @selector(init), (IMP)new_$_NSArray_$_init, &old_$_NSArray_$_init);
    hook(CLS(NSMutableArray), @selector(init), (IMP)new_$_NSMutableArray_$_init, &old_$_NSMutableArray_$_init);
    hook(CLS(NSPlaceholderArray), @selector(init), (IMP)new_$_NSPlaceholderArray_$_init, &old_$_NSPlaceholderArray_$_init);
    hook(CLS(NSArrayI), @selector(init), (IMP)new_$_NSArrayI_$_init, &old_$_NSArrayI_$_init);
    hook(CLS(NSArrayM), @selector(init), (IMP)new_$_NSArrayM_$_init, &old_$_NSArrayM_$_init);


    NSArray *a = [NSArray alloc];
    NSLog(@"NSArray before init: %@<%p>", a.class, a);

    a = [a init];
    NSLog(@"NSArray after init: %@<%p>", a.class, a);

    NSArray *al = @[];
    NSLog(@"Array literal: %@<%p>", al.class, al);

    NSMutableArray *ma1 = [a mutableCopy];
    NSLog(@"NSMutableArray (copied): %@<%p>", ma1.class, ma1);

    NSMutableArray *ma2 = [NSMutableArray alloc];
    NSLog(@"NSMutableArray (manufactured) before init: %@<%p>", ma2.class, ma2);

    ma2 = [ma2 init];
    NSLog(@"NSMutableArray (manufactured) after init: %@<%p>", ma2.class, ma2);

    return 0;
}
static GSPlaceholderArray   *defaultPlaceholderArray;
+ (void) initialize
{
    defaultPlaceholderArray = (GSPlaceholderArray*)
        NSAllocateObject(GSPlaceholderArrayClass, 0, NSDefaultMallocZone());
}

+ (id) alloc
{
    return defaultPlaceholderArray;
}
NSArray *a1 = [NSArray alloc];
NSArray *a2 = [NSArray alloc];
NSLog(@"%p, %p", a1, a2);

> "0x100102f30, 0x100102f30"