语言正则表达式入门-python代码

终于明白那些年知其然而不知其所以然的iOS内存管理方法

题记

本文介绍了Python对于正则表达式的支持,包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例。

正则表达式在很多的应用中都有使用到,特别是在网络爬虫中格式化html后取出自己需要的属性,在字符串的匹配和查找中也有很多的应用。

本文主要使用python对正则表达式进行说明,并配合合适的代码。

前言

自打自开始修iOS的时节,身边的情侣、网上的博客都告知我iOS的内存管理是乘引用计数的,然后说引用计数超过1则靶保存在内存的积聚中假如引用计数等于0则对象销毁。然后又说当所谓的ARC时代,强指针指向一个靶,则对象非销毁;一个目标没外一个强指针指于则销毁….,最后,我怀念说这些都蛮有道理的规范,但是,我要无知情为什么引用计数器为0为什么会于销毁,为什么一个对象没强指针指向就是会见销毁,为什么以@property中一个OC对象要动strong进行修饰
…. 。所以,在攻 Objective-C高级编程:iOS与OS
X多线程和内存管理
继,让自己懂得了成千上万政工。以下是于当下本书里面知识之总结性内容,如果如详细了解,请看该书籍。

留意:下面的始末是相符为已经对iOS内存管理有自然了解的程序员

怎么样配合手机号码

正则表达式的规则,一开始看之上,会感觉到规则太多尽乱,毫无规律可搜索,看罢了几乎个例证以后,慢慢的觉察有的常用之表达式以后,写于后的条条框框就是容易得多矣。

此处因怎样配合手机电话号码为例子

极端简单易行的无绳电话机规律也11单数字,正则表达式为:

\d{11}

这么我们即便以为凡事字符串中产生11位数字就是看是手机号码,但是现实中还有另外一些条条框框,12345678912即吗是11独数字,但是咱今天连无见面觉得他是手机号码,所以越来越的管规则写细了。

咱们尚好更的细致分为,13x开,14x开,17(13678)开头,18x初步,后面又带来8号的数字,还有其余一样种状态是170底情景,其中第四个呢[0589]惨遭的一个屡屡,再带来7位数字。
表达式可以写吧:

(13\d|14[57]|15[^4,\D]|17[13678]|18\d)\d{8}|170[0589]\d{7}

内存管理的考虑方式

  • 协调别的目标,自己所有
  • 匪自己变的对象,自己吗克具备
  • 不再用协调有所对象时放
  • 免友好装有的靶子无法自由

  • 和谐变的对象,自己拥有

以iOS内存管理着生四单重点字,alloc、new、copy、mutableCopy,自身行使这些重要字来对象,那么我就是颇具了靶

    // 使用了alloc分配了内存,obj指向了对象,该对象本身引用计数为1,不需要retain 
    id obj = [[NSObject alloc] init]; 

    // 使用了new分配了内存,objc指向了对象,该对象本身引用计数为1,不需要retain 
    id obj = [NSObject new]; 
  1. 不自己变的目标,自己呢克抱有

    // NSMutableArray通过类方法array产生了对象(并没有使用alloc、new、copy、mutableCopt来产生对象),因此该对象不属于obj自身产生的
    // 因此,需要使用retain方法让对象计数器+1,从而obj可以持有该对象(尽管该对象不是他产生的)
    id obj = [NSMutableArray array];
    [obj retain];
  1. 不再需要好具有对象时释放

    id obj = [NSMutableArray array];  
    [obj retain];

    // 当obj不在需要持有的对象,那么,obj应该发送release消息
    [obj release];
  1. 束手无策自由非自己独具的目标

    // 1. 释放一个已经释放的对象
    id obj = [[NSObject alloc] init];

    // 已经释放对象
    [obj release];

    // 释放了对象还进行释放
    [obj release];


    // 2. 释放一个不属于自己的对象
    id obj1 = [obj object]; 

    // obj1没有进行retain操作而进行release操作,使得obj持有对象释放,造成了野指针错误
    [obj1 release];

而达到吗iOS进行内存管理之季栽思维方式(记住不论是ARC还是MRC都照该想方式,只是ARC时代这些干活儿被编译器做了)

正则表达式语法

我们刚刚用到的\d
在正则表达式中,代表正在数字的意,还可据此[0-9]来代表一个数字。语法比较多,但是常用之并无是成百上千,图备受意味的是大的语法。

字符串匹配:

语法 含义
\d 数字
\D 非数字
\s 空白符
\S 非空白符
\w 单词字符
\W 非单词字符

数码相当:

语法 含义
* 匹配前面字符0次到无限次
+ 匹配前面字符1次到无限次
匹配前面字符0到1次
{m} 匹配前面字符m次
{m,n} 匹配前面字符m到n次

相当边界:

语法 含义
^ 匹配字符串开头
$ 匹配字符串末尾

祈求中的表达式都有专门的事例介绍,可以大体的探访,需要采取的当儿在专门来进行询问。

引用计数器讨论

苹果对此引用计数的管理是由此一样摆放引用计数表进行管制的

援计数表.png

我们平常在操作对象的援计数器时,其实就算是本着是引用计数表进行操作,在博到该表的地点和相应对象的内存地址,就足以经对象的内存从该表中进行索引获取到相应的援计数值,然后因用户的操作来回到计时器、计时器加1、计时器减1,脚就深深座谈retain、release、alloc、dealloc具体怎么操作该引用计数表

python中的re模块

当python中,有特别的模块来当正则表达式,就是re模块。

alloc

当我们调用alloc函数时我们更会调用allocWithZone方法

    id obj = [[NSObject alloc] init];


    + (id)alloc {
        return [self allocWithZone:NSDefaultMallocZone()];
    }

    + (id)allocWithZone:(NSZone*)z {
        return NSAllocateObject(self,0,z);
    }

调用NSAllocateObject函数对内存进行分配

字符串是否配合规则

本在用户注册里,我们渴求用户输入的手机号码,符合手机号码的规律,可以据此正则表达式来界定。

查字符串中
是否来符合要求的字符串,还是以刚才底手机号码为例:

import re
str = '15259340987'
# 将正则表达式编译成Pattern对象
pattern = re.compile('152\d{8}')
# 使用Pattern匹配文本,获得匹配结果,无法匹配时将返回None
match = pattern.match(str)
if match:
    # 使用Match获得分组信息
    print match.group()

这里可以视正则表达式,用之凡

re.compile('152\d{8}')

此表达式比

(13\d|14[57]|15[^4,\D]|17[13678]|18\d)\d{8}|170[0589]\d{7}

举凡从严非常多之,他才相当,152开始的手机号码,当然表达式可以依据你协调的内需来选,这里只是于一个实例。

retain、release、retainCount

该书籍对于这三单函数调用先是使GNUstep(一个Cocoa框架的换框架,功能类似)进行教学,后来以教了苹果对引用计数的兑现。在此地我们就是谈谈苹果之落实了。

调用retain、release、retainCount时函数调用顺序:

retain、retainCount、release函数调用顺序.png

一般来说所示,调用各个函数时会调用__CFDoExternRefOperation函数,该函数包含于CFRuntime.c中,该函数简化代码如下:

- (NSUInteger)retainCount 
{
    return (NSUInteger)__CFDoExternRefOperation(OPERATION_retainCount,self);
}

- (id)retain 
{
    return (id)__CFDoExternRefOperation(OPERATION_retain,self);
}

- (void)release 
{
    return __CFDoExternRefOperation(OPERATION_release,self);
}

    int __CFDoExternRefOperation(uintptr_r op,id obj) {
        CFBasicHashRef table = 取得对象对应的散列表(obj);
        int count;

        switch(op) {
            case OPERATION_retainCount: 
                count = CFBasicHashGetCountOfKey(table,obj);
                return count; 
            case OPERATION_retain: 
                CFBasicHashAddValue(table,obj);
                return obj; 
            case OPERATION_release: 
                count = CFBasicHashRemoveValue(table,obj):
                return 0 == count;
        }
    }

代码如齐所示,可以想像苹果就是运类于上述的援计数表来管理内存,也就是说我们于调用retain、retainCount、release时首先调用__CFDoExternRefOperation进而获得到引用技术表的内存地址以及以对象的内存地址,然后因目标的内存地址在说明中询问得到到引用计数值。

若是retain就加1
倘若retainCount就直回到值,
假定release则减1而且当CFBasicHashRemoveValue中将引用计数减少至0时会晤调用dealloc,从而调用NDDeallocateObject函数、free函数将对象所在内存释放

如上就是以谈论苹果对于引用计数的保管措施,对于GNUStep办法要自行查阅书籍

招来来具有符合规则的字符串

在网页爬虫中,我们得找有网页的游说出链接,用刚刚则匹配就非常容易做到,查看网页源代码中之html,带有网页链接的代码为

href="http://tech.sina.com.cn/t/2017-08-17/doc-ifykcppx8531845.shtml"

正则表达式可以形容成:

href="(.*?)"

python代码为:

import re
str = 'href="http://tech.sina.com.cn/t/2017-08-17/doc-ifykcppx8531845.shtml"'
# 匹配
links = re.findall('href="(.*?)"', str)

for link in links:
    print link

# 输出为: 
# http://tech.sina.com.cn/t/2017-08-17/doc-ifykcppx8531845.shtml

搜来了颇具需要的链接。

autorelease

图:将对象放入自动释放池中,当起释放池销毁时对活动释放池中之对象还进展相同不行release操作
书写形式:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    id obj = [[NSObject alloc] init];

    [obj autorelease];

    [pool drain];   

对autorelease的兑现方式,书籍也相比了GNUSetp与苹果实现的方,现在经GNUStep源代码来掌握苹果的贯彻

  1. GNUStep实现

    id obj = [[NSObject alloc] init];
    [obj autorelease];

    - (id)autorelease {
        [NSAutoreleasePool addObject:self];
    }

    + (void)addObject:(id)anObject {
        NSAutoreleasePool *pool = 取得正在使用的Pool对象;  
        if (pool != nil) {
            [pool addObject:anObject];
        }else {
            NSLog(@"NSAutoreleasePool非存在状态下使用Pool对象");
        }
    }

    - (void)addObject:(id)anObject {
        [array addObject:anObject];
    }

于上面可以看到,自动释放池就是通过数组完成的,我们当调用autorelease时最终便是将按部就班对象上加至眼前机动释放池的数组
如果针对于活动释放池销毁时对数组中之拓同样不行release操作,见下

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    ... 
    // 当自动释放池销毁时
    [pool drain];

    - (void)drain {
        [self dealloc];
    }

    - (void)dealloc {
        [self emptyPool];
        [array release];
    }

    - (void)emptyPool {
        for (id obj in array) {
            [obj release];
        }
    }
  1. 苹果之落实

    class AutoreleasePoolPage 
    {
        static inline void *push() 
        {
            相当于生成或持有NSAutoreleasePool类对象
        }

        static inline void *pop(void *token)
        {
            相当于废弃NSAutoreleasePool类对象
            releaseAll();
        }

        static inline id autorelease(id obj)
        {
            相当于NSAutoreleasePool类的addObject类方法   
            AutoreleasePoolPage *autoreleasePoolPage = 取得正在使用的AutoreleasePoolPage实例; 
            autoreleasePoolPage->add(obj);
        }

        id *add(id obj) 
        {
            将对象追加到内部数组中
        }

        void releaseAll() 
        {
            调用内部数组中对象的release实例方法 
        }
    };

    void *objc_autoreleasePoolPush(void)
    {
        return AutoreleasePoolPage::push();
    }

    void objc_autoreleasePoolPage(void *ctxt)
    {
        AutoreleasePoolPage::pop(ctxt);
    }

    id *objc_autorelease(id obj) 
    {
        return AutoreleasePoolPage::autorelease(obj);
    }

假设达到所示,苹果中采用了类似于GNUStep中之构思,将目标上加进数组进行保管

re模块中任重而道远之接口

  • re.compile(pattern, flags=0)

    本条方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象。
    第二只参数flag是配合模式,取值可以采取按位或运算符’|’表示又生效,比如re.I
    |
    re.M。另外,你呢得以当regex字符串中指定模式,比如re.compile(‘pattern’,
    re.I | re.M)与re.compile(‘(?im)pattern’)是齐价格的。

    语句

    prog = re.compile(pattern)
    result = prog.match(string)

    result = re.match(pattern, string)
    顶,第二种写法较为便利。

  • re.search(pattern, string, flags=0)

    本条方式用于查找字符串中得以匹配成功之子串。从string的pos下标处起尝试匹配pattern,如果pattern结束时以只是配合,则赶回一个Match对象;若无法配合,则拿pos加1后再行尝试匹配;直到pos=endpos时照回天乏术配合则归None。
    pos和endpos的默认值分别吗0以及len(string));re.search()无法指定这半独参数,参数flags用于编译pattern时指定匹配模式。

  • re.match(pattern, string, flags=0)

    这法子将自string的pos下标处起尝试匹配pattern;如果pattern结束时照只是配合,则赶回一个Match对象;如果匹配过程中pattern无法匹配,或者配合未竣工就是都到达endpos,则归None。
    pos和endpos的默认值分别吗0跟len(string);re.match()无法指定这简单单参数,参数flags用于编译pattern时指定匹配模式。
    注意:这个方法并无是全然匹配。当pattern结束时若string还闹剩余字符,仍然视为成功。想如果完全配合,可以于表达式末尾加上边界匹配符’$’。

  • re.split(pattern, string, maxsplit=0, flags=0)

    随能配合的子串将string分割后返回列表。maxsplit用于指定最酷分割次数,不点名将尽分割。

  • re.findall(pattern, string, flags=0)

    摸string,以列表形式返回全部克配合的子串。

  • re.sub(pattern, repl, string, count=0, flags=0)

    运用repl替换string中各一个匹配的子串后返回替换后底字符串。
    当repl是一个字符串时,可以使\id或\g

ARC中内存管理艺术

介绍
关于这部分之内存,作者是劈了个别有的开展座谈,第一有介绍ARC管理所需要的要字__strong
、__weak、__unsafe_unretained、__autoreleasing的打算;第二片段介绍了ARC针对于这些关
键字的现实性内任管理落实方式。下面我们尽管综合两局部的内容开展同样差座谈

苹果官方文档说ARC是起”编译器自行开展管理”,但实则只是是编译器是不够,需要满足下面啷个原则

  • clang(LLVM编译器)3.0以上
  • objc4 Objective-C运行时库493.9之上

常用之正则表达式语句

  • 相当邮箱:\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+.)+[A-Za-z]{2,14}

  • 匹配汉语:[\u4e00-\u9fa5]

  • 匹配IP(IPV4):(\d+).(\d+).(\d+).(\d+)

  • 配合身份证:\d{15}|\d{17}[0-9Xx]

  • 相当配手机号:(13\d|14[57]|15[^4,\D]|17[13678]|18\d)\d{8}|170[0589]\d{7}

__strong

正则表达式工具

正则表达式语法比较复杂,开始没经历的语句,调试起来比较费心,现在网上发好多的正则表达式工具,能帮忙我们飞速的拓展考查。有客户端的家伙为发web工具,用起都较为便利。

故此的比较多的凡RegexBuddy这无异于慢慢悠悠工具,如图,他好活动的转各种语言版的正则表达式的例证:
如下

语言 1

重复多入门教程可以参照:[http://www.bugingcode.com/python_start/]
(http://www.bugingcode.com/python_start/)

作用
    id __strong obj = [[NSObject alloc]init];

倘齐代码,表示obj这个强指针指向NSObject对象,且NSObject对象的援计数为1

    id __strong obj1 = obj; 

要达到代码,表示obj1之强指针与obj指针指为同一个NSObject对象,且NSObject对象的援计数为2

    id __strong obj = [NSMutableArray array];

使齐代码,表示obj这个强指针指向的NSMutableArray对象的援计数为1

综上所示,当一个靶被强指针指于则援引计数就加以1,否则,该目标没一个强指针指为则自动释放内存

那么问题来了,为什么一个目标为强指针指向引用计数就加1呢?
为什么分配在积中的目标内存能够自行释放内存?

原理

先是种植状况: 对象是透过alloc、new、copy、multyCopy来分配内存的

    id __strong obj = [[NSObject alloc] init];

当以alloc、new、copy、multyCopt进行对象内存分配时,强指针直接对一个援计数为1底靶子,在编译器作用下,上述代码会变换成为以下代码

    id obj = objc_msgSend(NSObject,@selector(alloc));
    objc_msgSend(obj,@selector(init));

    // 当让这个代码会在合适的时候被调用,不是马上调用
    objc_release(obj);

其次种情景:
对象非是自我变化,但是我拥有(一般这样的目标是透过除alloc、new、copy、multyCopy外方法发生的)

    id __strong obj = [NSMutableArray array];

于这种景象下,obj也针对一个引用计数为1之目标内存,其当编译器下更换的代码如下:

    id obj = objc_msgSend(NSMutableArray,@selector(array));

    // 代替我们调用retain方法,使得obj可以持有该对象
    objc_retainAutoreleasedReturnValue(obj);
    objc_release(obj);

就此使obj指于了一个引用计数为1之目标,
不了,objc_retainAutoreleaseReturnValue有一个成对的函数objc_autoreleaseReturnValue,这有限独函数可以用来最优化程序的运转
一般来说代码:

    + (id)array 
    {
        return [[NSMutableArray alloc] init];
    }

代码转换如下:

    + (id)array 
    {
        id obj = objc_msgSend(NSMutableArray,@selector(alloc));
        objc_msgSend(obj,@selector(init));

        // 代替我们调用了autorelease方法
        return objc_autoreleaseReturnValue(obj);
    }

当换后底代码,我们好望见调用了objc_autoreleaseReturnValue函数且这函数会回去注册到活动释放池的对象,但是,这个函数有只性状,它会翻动调用方的下令执行列表,如果发现接
下会调用objc_retainAutoreleasedReturnValue则免见面返回注册到活动释放池的靶子要只是返回一个对象而已。

两者的关系图如下:

关系图.png

通过这些,我们就是足以通报为什么强指针指向一个靶,这个目标的援计数就加1

__weak

作用
    id __weak obj = [[NSObject alloc] init];

基于我们的知,可以了解NSObject对象在变化之后这就会让放,其主要由是__weak修饰的指针没有招对象中的援计数器的变型
因此,__weak修饰的指针常用于打破循环引用或者修饰UI控件,关于__weak修饰的指针引用场景这里不叙述,下面要介绍该规律

原理

俺们掌握弱指针有半点只意:一.
修饰的指针不会见滋生对的对象的援计数器变化 二.
当对的目标吃灭绝时,弱指针全部置为nil,
那么除了这些之外,我们还有一个万一说之就是,为什么我们
每当次中不可知数的以weak呢?

  1. 胡弱指针不见面招对的靶子的援计数器发生变化

    id __weak obj = [[NSObject alloc] init];

编译器转换后底代码如下:

    id obj;
    id tmp = objc_msgSend(NSObject,@selector(alloc));
    objc_msgSend(tmp,@selector(init));
    objc_initweak(&obj,tmp);
    objc_release(tmp);
    objc_destroyWeak(&object);

对于__weak内存管理为借助了看似于援计数表的表明,它通过对象的内存地址做呢key,而相应的指针作为value进行管理,在上述代码中objc_initweak就是做到这部分操作,而objc_destroyWeak
虽是绝迹该目标对应之value。所以,weak于修饰只是让weak表增加了记录没有引起引用计数表的转

  1. 当弱指针指向的对象呗销毁时,弱指针怎么才自动置为nil?
    为什么我们在程序中不克反复利用weak呢

靶通过objc_release释放对象内存的动作如下:

  • objc_release
  • 盖引用计数为0所以执行dealloc
  • _objc_rootDealloc
  • objc_dispose
  • objc_destructInstance
  • objc_clear_deallocating

假定以目标为扔时最后调用了objc_clear_deallocating,该函数的动作如下:

  1. 由weak表中得到已弃对象内存地址对应之具备记录
    2)将已弃对象内存地址对应的记录面临享有为weak修饰的变量都置为nil
    3)从weak表删除已弃对象内存地址对应之笔录
    4)根据已弃对象内存地址从引用计数表中找到呼应记录删除

准这可以解释为何对象为灭绝时对应之weak指针变量全部且置为nil,同时,也扣下销毁weak步骤比较多,如果大度运用weak的言语会加CPU的载荷
要是未建议大量以weak,还有一个由看下面的代码:

    id __weak obj1 = obj; 
    NSLog(@"obj2-%@",obj1);

编译器转换上述代码如下:

    id obj1; 
    objc_initweak(&obj1,obj);

    // 从weak表中获取附有__weak修饰符变量所引用的对象并retain 
    id tmp = objc_loadWeakRetained(&obj1);

    // 将对象放入自动释放池
    objc_autorelease(tmp);
    NSLog(@"%@",tmp);
    objc_destroyWeak(&obj1);

论这当我们走访weak修饰指针指向的靶子时,实际上是访问注册及机关释放池的目标。因此,如果大气运用weak的语,在我们失去拜访weak修饰的目标时,会有雅量对象注册及自动释放池,这会影响行程
程序的性。引进方案 :
要访问weak修饰的变量时,先用那给予给一个strong变量,然后进行走访

最终一个题材: 为什么访问weak修饰的目标就是会看注册及自动释放池的对象呢?

  • 因为weak不会见挑起对象的援计数器变化,因此,该目标在运转过程中那个有或会见受保释。所以,需要以对象注册及机关释放池中连当电动释放池销毁时放对象占的内存。

__unsafe_unretained

作用

__unsafe_unretained作用需要同weak进行自查自纠,它吧未会见惹对象的里引用计数器的变,但是,当其对的靶子吃销毁时__unsafr_unretained修饰的指针不会见置为nil。而且貌似__unsafe_unretained就同她的名字同样是匪安全,它不纳入ARC的内存管理

__autoreleasing

作用

ARC无效

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    id obj = [[NSObject alloc] init];
    [obj autorelease];
    [pool drain];

ARC有效*

    id __autoreleasing obj1 = obj;

设齐所示,通过__autoreleasing修饰符就得了ARC无效时一样的法力

当,在某个部分景下我们无经显式指定__autoreleasing关键字便得完成机关注册及自动释放池的效能,例如以下情形

第一种:

    @autoeleasepool {
        // 如果看了上面__strong的原理,就知道实际上对象已经注册到自动释放池里面了 
        id __strong obj = [NSMutableArray array];
    }

第二种:

访问__weak修饰的对象时,对象就是叫注册及了全自动释放池

第三种:

以下形式之默认修饰符是__autorelease

  • id *obj;
  • NSObject **obj;

并且,也引出一个题材:
为什么在@property中OC对象下strong而基本数据列应用assign?

属于性默认修饰符.png

自表中可以想见出,在ARC在OC对象的默认修饰符是__strong,因此,在@property中使用strong
设基本数据类是勿纳入到ARC内存管理中的,__unsafe_unretained也非归ARC管,因此,使用assign对基本数据类进行修饰

原理 “`objc @autoreleasepool {
    id __autoreleasing obj = [[NSObject alloc] init];
}

代码转换如下:  

```objc
    id pool = objc_autoreleasePoolPush(); 
    id obj = objc_msgSend(NSObject,@selector(alloc));
    objc_msgSend(obj,@selector(init));
    objc_autorelease(obj);
    objc_autoreleasePoolPop(pool);

    @autoreleasepool {
        id __autoreleasing obj = [NSMutableArray array];
    }

代码转换如下:

    id pool = objc_autoreleasePoolPush();
    id obj = objc_msgSend(NSMutableArray,@selector(array));
    objc_retainAutoreleasedReturnValue(obj);
    objc_autorelease(obk);
    objc_autoreleasePoolPop(pool);

上述代码,代表的虽是本人变化并拥有对象、自身不特别成但为有对象的片种植__autorelease内存管理状况

ARC规则

  • 无能够用retain、release、retainCount、autorelease方法(如果ARC下利用会并发编译错误)

  • 免克采取NSAllocateObject、NSDeallocateObject函数(如果ARC下以会出现编译错误)

  • 并非显式调用dealloc(ARC下,显式调用dealloc并以代码中写[super
    dealloc]啊会见产出编译错误)

  • 使用@autoreleasepool块代替NSAutoreleasePool

    @autoreleasepool{}块相比较NSAutoreleasePool而言显得代码更加整洁、层次性强,而且@autoreleasepool代码快哉ARC或者非ARC下都是可以使用的
  • 得遵守内存管理命名规则

    1) alloc、new、copy、mutableCopy等以这些名字开头的方法都应当返回调用方能够持有的对象  
    2)init开头的方法必须是实例方法并且要返回对象,返回值要是id或者该方法对应类的对象类似或者其超类或者其子类。另外,init开头的方法也仅仅用作对对象进行初始化操作
  • 切莫可知下区域(NSZone)

    区域是以前为了高效利用内存的使用率而设计的,但是,目前来说ARC下的模式已经能够有效利用内存,区域在ARC下还是非ARC下都已经被单纯的忽略 
  • 针对象型变量不克作C语言结构体的积极分子

    OC对象型变量如果成为了C语言结构体的成员,那么,ARC不能掌握该对象的生命周期从而有效管理内存,因此,不能这样使用。 
  • 显式转换”id” 和 “void*”

    非ARC下:  
    id obj = [[NSObject alloc] init];
    void *p = obj; 
    这样的代码是可行的,id和void*可以方便得自由转化 ,但是,在ARC下是不一样的 

    ARC下id和void*有三个转换的关键字 __bridge、__bridge_retained、__bridge_transfer: 
    id obj = [[NSObject alloc] init]; 
    void *p = (__bridge void*)obj;

    注意: __bridge不会引起对象的引用计数变化,因此,安全性不太好。相比较,__bridge_retained不仅仅实现了__bridge的功能而且能让p调用retain方法使p持有对象。另外,
    __bridge_transfer也是和release方法类似,使用__bridge_transfer进行转化,既让对象p调用一次retain方法,而且原来指针obj会调用一次release方法也非常安全 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图