`
zjjzmw1
  • 浏览: 1352566 次
  • 性别: Icon_minigender_1
  • 来自: 开封
社区版块
存档分类
最新评论

ios笔记2

    博客分类:
  • iOS
阅读更多

iOS笔记2

Categories

CategoriesObjective-C里面最常用到的功能之一。基本上category可以让我们给已经存在的类增加方法,而不需要增加一个子类。而且不需要知道它内部具体的实现。

 

如果我们想增加某个framework自带的类的方法,这非常有效。如果我们想在我们程序工程的NSString能够增加一个方法,我们就可以使用category。甚至都不需要自己实现一个NSString的子类。

 

 

 

比如,我们想在NSString里面增加一个方法来判断它是否是一个URL,那我们就可以这么做:

 

#import

 

@interface NSString (Utilities)

 

- (BOOL) isURL;

 

@end

 

这跟类的定义非常类似。区别就是category没有父类,而且在括号里面要有category的名字。名字可以随便取,但是习惯叫法会让人比较明白category里面有些什么功能的方法。

 

这里是具体的实现。但是要注意,这本身并不是一个判断URL很好的实现。我们主要是为了整体的了解category的概念。

 

#import "NSString-Utilities.h"

 

@implementation NSString (Utilities)

 

- (BOOL) isURL

 

{

 

if ( [self hasPrefix:@"http://"] )

 

return YES;

 

else

 

return NO;

 

}

 

@end

 

 

 

现在我们可以在任何的NSString类对象里都可以调用这个方法了。下面的代码在console里面打印的"string1 is a URL"

 

NSString* string1 = @"http://www.CocoaDev.cn/";

 

NSString* string2 = @"Pixar";

 

if ( [string1 isURL] )

 

NSLog (@"string1 is a URL");

 

if ( [string2 isURL] )

 

NSLog (@"string2 is a URL");

 

跟子类不一样,category不能增加成员变量。我们还可以用category来重写类原先的存在的方法,但是这需要非常非常小心。

 

记住,当我们通过category来修改一个类的时候,它对应用程序里的这个类所有对象都起作用。

隐藏xcode command+h

退出xcode command+q

关闭窗口 command+w

关闭所有窗口 command+option+w

关闭当前项目 command+control+w

关闭当前文件 command+shift+w

保存文件 command+s

保存所有文件 command+option+s

 

还原到保存时状态 command+u

 

项目中查找 command+shift+F

查找下一个 command+g

查找上一个 command+shift+g

 

浏览源文件 command+Double Click

打开头文件 command+shift+d

切换头/源文件 command+option+上箭头

撤销 command+z

重复 command+shift+z

粘贴并匹配格式 command+option+shift+v

 

文件首行 command+上箭头

文件末 command+下箭头

行首 command+左箭头

行末 command+右箭头

上一单词 option+左箭头

下一单词 option+右箭头

上一拆分单词 control+左箭头

下一拆分单词 control+右箭头

 

Tab :接受代码提示

Esc :显示代码提示菜单

 

下个Build警告或错误 command+=

前个Build警告或错误 command+shift+=

以调试方式运行程序 command+y

继续(在调试中)command+option+p

编译运行 command+r

 

Xcode 代码格式化/自动排版:

 

Xcode 版本:4.24.2之前的版本

选中需要格式化代码 -> Edit -> Format ->Re-Indent

Xcode 版本:4.2之后的版本

选中需要格式化代码 -> Editor -> Structure ->Re-Indent 或者

选中需要格式化代码 -> 右击 ->选中 Structure ->Re-Indent

 

 

nonatomic assign retain copy readonly readwrite //对象的创建和使用;

singleton

alloc copy retain release autorelease strong weak //堆栈内存管理

 

kvc kvo NSNotificationCenter NSNotification

category Extention protocol

科比VS韦德

21世纪是一个崇拜强者的世纪

MJ可以称做为神这是毋庸质疑的

而这个世纪初冒出了两个最接近MJ的人

他们分别是科比,韦德

 

那么他们两个到底谁更强悍呢

 

我说

科比是个凡人

他天赋并不是太高

你看他弹跳不如卡特

你看他启动稍逊麦迪

你看他速度不比答案

3分球也不如雷阿伦

有许许多多的人在一些方面强于他

可是就算如此

在常规赛里

只有他享受从第一节到最后都是受对手两人以上的防守

仅仅是为了不让他再拿81的高分吗

 

再看韦德

我认为他着MJ一样的天赋

他和MJ只是身高差了5CM而已

看了昨天比赛的人都知道

热火落后湖人7分时

韦德在科比接球的一瞬间抢断得手

随后热火将比分扳平\加时

这让我想到了MJ抢断马龙然后绝杀那一幕

韦德突破直接造成科比一次打手犯规

韦德还用晃动骗得科比起跳使其犯规送自己上罚球线

在数数韦德的罚球,不知道是不是这个赛季罚球次数最多的

韦德的突破分球让热火获得了很多的罚球机会

这不是说明韦德的篮球智商很高吗

韦德还是去年总决赛的MVP

反观科比

白巧克力上篮时他完全可以将其封盖可他可他没有

波西就站在科比面前想试投3分解说员替科比说不信他敢投结果热火3分入帐

还有科比一些超级困难的出手

有些是进了但很多都没有进

韦德却很少出现这样的情况

科比在比赛中脸上的表情很丰富

而韦德只有平静

可在心里边到底谁更平静

谁又更能集中精神

只有他们自己知道

 

如此看来

韦德更象MJ

但科比作为一个凡人

他知道要弥补自己天分上的不足

只有靠平时努力的练习

他是现役球员中最勤奋的

决不向命运低头,永不放弃

他的精神面貌才是我们最值得学习的

 

是凡人不要紧

在比赛中犯一些连我们打球会犯的错误也不要紧

科比会用随后的行动来证明自己的价值

会过程来诠释什么叫天分!

 

人生就象一场旅行

不必在乎目的地

在乎的只是沿途的风景

以及看风景的心情

 

平时过程中自己尽了力

又何必追求完美呢

我认为科比做到了这一点

所以我是科迷

在他丫的退役之前

他就是我认为最强的球星

 

我甚至认为科比一定会超越MJ

因为科比正在超越自我

而韦德也在用自己独特的方式在追赶

NBA需要这样的历程

要不你怎么会关注NBA

偶像超越了谁确切的来讲不关我的事

他们需要不断的挑战

没有悬念的比赛不值得去欣赏

科比最需要的是挑战他自己本人

 

让我们继续关注科比布莱恩特的篮球

静待他能在退役前证明自己不比MJ

 

Objective-C中类属性的 copy, retain, assign , readonly , readwrite, nonatomic区别

nonatomic:非原子性访问,对属性赋值的时候不加锁,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问。

atomicObjc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。)

 

assign: 简单赋值,不更改引用计数

对基础数据类型 (例如NSInteger)和C数据类型(int, float, double, char, 等) 适用简单数据类型或对指针的弱引用

 

copy:建立一个索引计数为1的对象,然后释放旧对象对NSString

 

retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1

对其他NSObject和其子类

 

@property (nonatomic, assign) int number;

这里定义了一个int类型的属性,那么这个int是简单数据类型,所以用nonatomic, 不需要进行引用计数,所以用assign。适用于简单数据类型和指针的弱引用。

 

@property (nonatomic, copy) NSString * myString;

这里定义了一个NSString类型的属性,不需要原子操作,所以用nonatomic.

为什么需要copy,而不是retain呢!因为如果对myString赋值原字符串是一个可变的字符串(NSMutableString)对象的话,用retain的话,当原字符串改变的时候你的myString属性也会跟着变掉。我想你不希望看到这个现象。实际上博主测试,如果原来的字符串是NSString的话,也只是retain一下,并不会copy副本

 

@property (nonatomic, retain) UIView * myView;

这里定义了一个UIView类型的属性,不需要原子操作,所以用nonatomic.

当对myView 赋值的时候原来的UIView对象retainCount会加1

 

//接口文件

@interface MyClass : NSObject

@property (nonatomic, assign) int number;

@property (nonatomic, copy) NSString * myString;

@property (nonatomic, retain) UIView * myView;

@end

 

//实现文件

@implementation MyClass

@synthesize number;

@synthesize myString;

@synthesize myView;

 

//释放内存

-(void) dealloc

{

[myString release]; //copy的属性需要release;

[myView release]; //retain的属性需要release;

 

[super dealloc]; //传回父对象

}

 

@end

 

假如你有一段代码创建了一个MyClass对象

 

MyClass * instance = [MyClass alloc] init];

 

//number赋值,没什么可说的,简单数据类型就这样

instance.number = 1;

 

//创建一个可变字符串

NSMutableString * string = [NSMutableString stringWithString:@"hello"];

 

instance.myString = string; //myString赋值

 

[string appendString:@" world!"]; //string追加文本

 

NSLog(@”%@”,string); //此处string已经改变,输出为 “hello world!”

 

NSLog(@”%@”,instance.myString); //输出myString,你会发现此处输出仍然为 “hello” 因为 myStringstring改变之前已经copy了一份副本

 

UIView * view = [[UIView alloc] init];

NSLog(@”retainCount = %d”,view.retainCount);

//输出view的引用计数,此时为1

 

instance.myView = view; //myView属性赋值

 

NSLog(@”retainCount = %d”,view.retainCount);

//再次输出view的引用计数, 此时为2,因为myViewview进行了一次retain

 

[view release];

//此处虽然viewrelease释放掉了,但myViewview进行了一次retain,那么myView保留的UIView的对象指针仍然有效。

 

[instance release] ;

// Setup two variables to point to the same string

NSString * str1 = @"Hello World";

NSString * str2 = str1;

 

// "Replace" the second string

str2 = @"Hello ikilimnik";

 

// And list their current values

NSLog(@"str1 = %@, str2 = %@", str1, str2);

 

 

 

output:str1 = Hello World, str2 = Hello ikilimnik

 

 

 

Mutable strings

 

// Setup two variables to point to the same string

NSMutableString * str1 = [NSMutableString stringWithString:@"Hello World"];

NSMutableString * str2 = str1;

 

// "Replace" the second string

[str2 setString:@"Hello ikilimnik"];

 

// And list their current values

NSLog(@"str1 = %@, str2 = %@", str1, str2);

 

 

 

output:str1 = Hello ikilimnik, str2 = Hello ikilimnik

 

 

 

注意,当你使用不可变的NSString class时,替换旧的字符串的唯一方式就是创建一个新的字符串然后更新你的变量“str2”

 

来指向这个新的字符串。这个操作不会影响“str1”所指向的内容,因此它将继续指向初始的字符串。

 

 

 

NSMutableString的例子里,我们没有创建第二个字符串,而是通过改变已经存在的可变字符串“str2”的内容来代替。

 

由于str1str2两个变量都仍然指向同一个字符串对象,从nslog中可以看到它们值都将会被更新。

 

 

 

理解指针变量和它实际指向对象的不同是非常重要的。一个NSString对象是不可变的,但是这并不阻止你改变指向这个不

 

可变对象的指针的值。

 

 

 

"NSString *"这个数据类型代表一个NSString对象的指针,不是NSString对象本身。

 

"NSMutableString *"这个数据类型则是代表"NSMutableString"对象本身,这两者是有区别的。

 

 

 

这也是有的时候我们使用NSMutableString类型字符串时,要使用copy的原因,因为可能不想改变新的字符串时影响到旧的字符串的值。

 

如:

 

NSMutableString * str2 = [str1 mutableCopy];

 

p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo}

Objective-C指针赋值时,retain count不会自动增加,需要手动retain

 

ClassA *obj1 = [[ClassA alloc] init]; //retain count = 1

 

ClassA *obj2 = obj1; //retain count = 1

 

[obj2 retain]; //retain count = 2

 

[obj1 hello]; //输出hello

 

[obj1 release]; //retain count = 2 – 1 = 1

 

[obj2 hello]; //输出hello

 

[obj2 release]; //retain count = 0,对象被销毁

 

问题解决!注意,如果没有调用[obj2 release],这个对象的retain count始终为1,不会被销毁,内存泄露。

Objective-C中引入了autorelease pool(自动释放对象池),在遵守一些规则的情况下,可以自动释放对象。(autorelease pool依然不是.Net/Java那种全自动的垃圾回收机制

 

Objective-C的对象生成于堆之上,生成之后,需要一个指针来指向它。

 

ClassA *obj1 = [[ClassA alloc] init];

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics