在cocoa application的应用中,我们有时会使用Core Foundation(CF),我们经常会在Objective-C和CF之间进行转化。系统使用arc的状态下,编译器不能自动管理CF的内存,这时候你必须使用CFRetain和CFRelease来进行CF的内存的管理。
具体的CF内存管理规则见: Memory Management Programming Guide for Core Foundation
在OC和FC之间进行转化的时候,主要是对象的归属问题。共有两种方式:
1、使用宏,可以标识归属者从OC到CF,还是从CF到OC。
NS_INLINE CFTypeRef CFBridgingRetain(id X) {
return (__bridge_retain CFTypeRef)X;
}
NS_INLINE id CFBridgingRelease(CFTypeRef X) {
return (__bridge_transfer id)X;
}
2、使用转化符,如:__bridge,__bridge_transfer,__bridge_retained
id my_id;
CFStringRef my_cfref;
…
NSString *a = (__bridge NSString*)my_cfref; // Noop cast.
CFStringRef b = (__bridge CFStringRef)my_id; // Noop cast.
…
NSString *c = (__bridge_transfer NSString*)my_cfref; // -1 on the CFRef
CFStringRef d = (__bridge_retained CFStringRef)my_id; // returned CFRef is +1
下面以详细的例子来介绍一下OC和CF在arc下内存管理的详细写法.下面以CFURLCreateStringByAddingPercentEscapes()函数为例说一下在ARC下的写法和非ARC下的写法。
非ARC模式下的写法:
#pragma mark – View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"=%@", [self escape:@"wangjun"]);
}
-(NSString *)escape:(NSString *)text
{
return (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef)text,
NULL,
CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));;
}
使用instruments检测,没有内存泄漏。
下面把上面工程改为arc模式。
可以看到xcode自动把上面函数转化为:
#pragma mark – View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"=%@", [self escape:@"wangjun"]);
}
-(NSString *)escape:(NSString *)text
{
return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef)text,
NULL,
CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));;
}
在arc中,CF和OC之间的转化桥梁是 __bridge,有两种方式:
- __bridge_transfer ARC接管管理内存
- __bridge_retained ARC释放内存管理
上面的方法是从CF转化为OC NSString对象,使用的__bridge_transfer ,对象所有者发生转变,由CF到OC,最后由ARC接管内存管理。运行上面的代码,用instruments检测,是没有内存泄漏的。
上面代码等同于:
- (NSString *)escape:(NSString *)text
{
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef)text,
NULL,
CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)));}
如果将上述代码改为:
-(NSString *)escape:(NSString *)text
{
return (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef)text,
NULL,
CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));;
}
编译也会成功,但是这时候用instruments检测,可以发现内存泄漏:
由于CF转化完OC,没有自己释放内存,同时也没有把内存管理交给ARC,所以出现内存泄漏。由于__bridge只是同一个对象的引用,内存的所有权没有发生变化。
下面在说一下oc到CF的转化,需要把OC的内存管理权释放掉。
NSString *s1 = [[NSString alloc] initWithFormat:@"Hello, %@!", name];
CFStringRef s2 = (__bridge_retained CFStringRef)s1;
// do something with s2 // . . .
CFRelease(s2);
最后由CF进行内存释放。
上面代码等同于:
CFStringRef s2 = CFBridgingRetain(s1);
// . . .
CFRelease(s2);
下面总结一下我们使用ARC情况下。oc和CF互相转化的原则:
- CF转化为OC时,并且对象的所有者发生改变,则使用CFBridgingRelease()或__bridge_transfer 。
- OC转化为CF时,并且对象的所有者发生改变,则使用CFBridgingRetain()或__bridge_retained
- 当一个类型转化到另一种类型时,但是对象所有者没有发生改变,则使用__bridge.
1.联通的李浩宇的演讲
我知道联通是国内最好的3G网络提供商,他们有最好的硬件为3G网络提供支撑。没办法,在中国垄断是硬道理!这些领域不是你去碰就给你碰的。
2.当乐肖永泉
我只知道当乐是个很烧钱的公司,原来我分析的中国无线互联企业收入超千万的公司名单上有这家公司。我原来合作的梦想兄弟的产品策划也去了当乐网。据说当乐从成立到现在已经烧进去3亿多资金了。
3. UC朱顺炎
我知道UC是做浏览器起家的,最初UC浏览器是一个WAP浏览器,那个时候手机流量很贵,网速慢,资费高,对于使用WAP方式上网的用户,流量是他们心中的痛。UC浏览器主要针对这部分人,不仅解决这些人的上网浏览问题,而且解决上网的节省流量问题,这是UC浏览器长期主打的诉求,而且由此建立了口碑。至此UC浏览器全球季活跃用户已经超过4亿,其中安卓的月活跃用户已经达到1亿。我感觉这样的企业不适合做游戏平台,它更适合走360的路子,因为这样比较对眼。不过UC出HTML5引擎可能对自己做平台打出很好的一剂重拳。
4.新浪游戏事业部俞佳
一听说话就知道是个干实事的人。他讲述了新浪微博在2012年做的探索。首先,页游转IOS用微博推很失败。每天2万用户在线,月收入过百万的页游通过微博每天放进去10万的用户,只有1000左右用户使用。其次微博上放广告,比如卖彩票。很OK!游戏推送之路还需探索。最后谈到尝试在HTML5页面上放图标方式来做推广是一个好的选择。中间他提到了中国生态链的恶劣,IOS刷榜很不爽!深有同感。
5. DeNA王勇
平台的区域差异化导致平台需要提供本土化的支持。看了平台也需要地域的个性化。
6. 金山互动娱乐陈睿
居然说HTML5在2-3年还火不起来,简直就是谬论!金山已经在和360的博杀中败下阵来。不过未来无线安全确实是个需求旺盛的产业,这点很认同。金山走的路线是先养用户再作为。里面讲到了三低的用户群体:低龄、低收入、低学历。他们对用户深度挖掘发觉用户充电时候大部分用户需要屏幕显示时钟或是天气。从这一点来说正印证了“宽一厘米,深一公里的道理”。找到简单的切入点,深入下去,大市场也许就在里面!
7.八百鸟创始人林青鸿
最活跃,最有深度的女性!她说话总是给人以激情,谈吐给人以快乐。她从营销推广的角度讲述了中小型的创业团队在推广的时候不花钱也可以做好推广。比如:FaceBook打广告;用自己最新动态在做宣传!其中讲到创业团队需要拿出Story,团队需要story。中国的抄袭也需要讲究方法,需要找到模仿对象的缺点,用自己的产品来弥补。最经典的话是:创新是copy的一种!
8.蓝港在线王峰
最直白,最真实的人。首先谈到移动互联网的商业化太浓;PC端游市场里很苦逼,没有朋友全是对手。建议大家不要做引擎开发这种重复造轮子的事了,用Unity3D和HTML5好了!创业者团队应该更关注产品本身。其次谈到现在烧钱的公司很多,坦言用钱砸不出大公司来。谈到运营时候说:没有成熟的运营就收不到钱,那么投资人就会不吊你,最终产品创意将和营收捆绑,导致的后果就不言而喻了。还说到触摸屏体验有颠覆性,PC和街机经验还没有融入手游。这点不太认同,正因为手游的巨大差异才不会让PC和街机的神话轻易在手游上复制。王峰还谈到了做游戏的很多经验,比如:网游的原形就决定了这款游戏能走多远,要创新就要先学习。创新就是不断的乱来。开放前的测试很重要。游戏能不能赚钱看运营.这两句是最能和我产生共鸣的话了!最后谈到游戏团队必须都热爱游戏,不热爱游戏的不要。在自己研发产品推出后需要和用户拉到最近的距离。
通过这次峰会想了很多,做技术型为导向的公司还是做用户为导向的公司,作用户为导向产品还是做概念为导向产品.这些一定要明确,应该把它提到战略的高度来考虑.我在想如果做一个企业大致有三个互相紧扣的环:目标、战略和战术。目标上,很多人都一样,都有一个很大的梦想,试图去做一个服务很多人的公司(未必是利润率最高的公司),战术上,是像迅雷和豆瓣,是做慢慢推进产品的数字公司,还是作360、淘宝这样的为用户服务的公司。但在战略的考虑上,像迅雷和豆瓣,杨勃就是典型的不急不躁,而邹胜龙并非如此。他要反思的原因就在于:他嫌自己慢了。这是一个可怕的想法。老马和老周都知道用户要什么,他们每一次并购都预示像弥补自己的软肋。
话转到移动互联网上来,在很长的时间里,大家坚持做一个细分的APP来满足用户,很多大公司也坚持把自己的APP分拆出来,做成APP群,每个细分产品一个独立的APP,去运营,去获取用户。大家都有个不敢苟同的认识,用户不需要大而全的APP,独立的细分APP可以做的更好,体验更优秀。但是,用户真的是不需要大而全的APP吗?我保持怀疑。
微信的出现,第一次使用了“插件系统”这个形式。也许这是微信最伟大的地方之一,也是未来微信最具有发展潜力的地方之一。因为插件系统的出现使得一个APP的扩展成为可能,同时,插件系统是一个用户自助的系统,且很灵活,这算是个天才的想法吧!
以下是借用360老周的话一上来就讲自己商业模式,一讲商业模式就是未来三年能赚多少钱。其实,这些创业者对什么是商业模式都没有搞懂,以为商业模式就是赚钱方法。他们不知道一个商业模式的核心是产品,本质是通过产品为用户创造价值。商业模式还包括定位、寻找需求最强烈的用户群,用聪明的推广方法接触到这些用户,在接触过程中不断把产品打磨好,等你有了巨大的用户基础,是一定能赚到钱的。但是,如果你急于想赚钱,对不起,运气好的话你可能赚点小钱,运气不好就直接完蛋。现在是需要想清楚自己的商业模式是什么的时候了!
这里再次推荐童鞋先看看这篇文章,以对Git的工作组成和分支概念有直观的了解
《Git分支管理是一门艺术》
分支的概念
了解分支前,我们需要了解提交commit这个概念,每个提交可以简单的理解成为一个快照。多次提交可以构成一个线性结构,1->2->3->...,类似单链表,一般的你可以把这条直线看作你的主分支--稳定版。
而分支相当于指向某个commit的分支,一般的,系统会自动使用master作为分支的默认名字,他指向最后一次提交。当你在master分支上的时候,每次你提交的时候,他都会随着你的commit前移,永远指向最新的。
当你创建新的分支test的时候,就像当与在此线性结构上开出一条新的走向,从单链表变成树,当你再次提交时,这个新的分支指针test会随着提交前移,就像之前的master一样。你可以切换回master,或者在test上再次创建分支,随着你不断创建分支,这个树的结构会变得非常复杂。甚至到难以解读的程度,因此,在正式工作时,一定要谨慎创建分支,每个分支的作用都要记清楚并在合适的时间与主分支合并。
你可以使用这个命令查看分支
git branch 查看分支
git branch -r 查看远程分支
git branch -a 查看所有分支
git branch --no-merge 查看所有未合并分支
git branch --merge 查看所有已经合并的分支
分支的创建,删除和切换
你可以用如下命令创建分支
git branch <newbranch>
切换到新的分支
git checkout <newbranch>
或者直接使用这个命令创建并切换到新分支
git checkout -b <newbranch>
你可意识用如下命令删除分支
git branch -d <newbranch>
但是未合并的分支不能使用这个命令来删除
如果你坚持删除未合并的分支,可以用这个命令
git branch -D <newbranch>
分支的合并
分支的合并可以将你的开发成果加入到产品中,合并的成功与否至关重要。因此Git对这部分非常重视。你可以使用这个命令将目标分支合并到当前分支(!!注意,是合并"到"你现在所在的分支)
git merge <destbranch>
举个例子,首先确认自己在master分支上,创建文件test,输入内容"2",提交,我建立并切换到分支test,向文件末尾输入内容"567",提交,切换回分支master,在文件末尾输入内容234.提交。此时合并,命令如下
#git checkout master(如果你不在master上)
#echo "2">test
#git commit -a -m "init"
#git checkout -b test
#echo "567">>test
#git commit -a -m "bemergedbranch"
#git checkout master
#echo "234">>test
#git commit -a -m "mergebranch"
#git merge test
Auto-merging test
CONFLICT (content): Merge conflict in test
Automatic merge failed; fix conflicts and then commit the result.
#git status
# On branch master
# Unmerged paths:
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: test
#
no changes added to commit (use "git add" and/or "git commit -a")
查看test内容
#cat test
2
<<<<<<< HEAD
234
=======
567
>>>>>>> test
可以看到以下三个分隔标志
<<<<<<< HEAD
=======
>>>>>>> test
这个内容简单明了,我就不多说了,合并时只需删除这些,并留下想要的内容即可。
比如,我觉得主分支上的内容比较合适,因此我删除
<<<<<<< HEAD
=======
>>>>>>> test
567
只留下
234
运行git merge
# On branch master
# Unmerged paths:
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: test
#
no changes added to commit (use "git add" and/or "git commit -a")
使用add将其提交
#git add test
一切ok了。从这里我们可以看到分支合并还是基于变化的,如果你先修改test,然后回到分支master,不修改master直接合并,那么可以看到分支会被直接合并掉。就算你把2改成3,4,5...这个很容易理解,就不多说了。
mergetool
重磅推出mergetool,一个神奇的工具。mergetool是一个可视化的工具。
输入命令
#git mergetool
最开始,他会让你选择使用什么工具,你可以选择适合自己的工具。
merge tool candidates: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis emerge vimdiff
Merging the files: test
Normal merge conflict for 'test':
{local}: modified
{remote}: modified
Hit return to start merge resolution tool (meld):
test seems unchanged.
我这里用的是默认的meld,meld的界面如下
修改过程一样,但是关系更加分明。
衍合
衍合的原理是回到两个分支的共同祖先,提取你所在分支每次提交产生的差异,然后将这些差异保存成临时文件(差异补丁文件,很好理解吧),然后从当前分支转换到你需要衍合入的分支,依序使用每个差异补丁文件。
频繁的衍合会极大的方便你的工作,但是请不要将它衍合进你的稳定版本。
关于衍合的妙用我体会的还不是很深。请有经验的童鞋指正。