`
mikixiyou
  • 浏览: 1085840 次
  • 性别: Icon_minigender_1
  • 来自: 南京
博客专栏
C3c8d188-c0ab-3396-821d-b68331e21226
Oracle管理和开发
浏览量:349291
社区版块
存档分类
最新评论

iOS开发(stanford2011)笔记第二课Objective-C关键知识点

    博客分类:
  • iOS
阅读更多

在第二课中,介绍了Objective-C 的一些关键知识点,包括点访问方法,strongweak 的比较,nil ,实例化,动态绑定技术(程序在执行时才会知道要执行的代码有没有),自省(选择器的使用),基础的框架如NSObject,NSString 等等。

这些是开发的基础,整理了一遍有利于程序的开发和调整。像类方法只能使用类来调用,实例方法只能使用实例,这点以前还没有明白。对于在实例中怎么不能调用类方法的问题还疑惑了一阵子。

 

1 、点符号方法访问属性变量

property 引进后开始使用这个方法,苹果官方解释为这样做是出于代码美观考虑。苹果的产品将美观放在第一位,这产品包括了obj-c 的代码。

使用点符号法self.propery 访问@property 比普通的[self property] 方法更直观。在C 结构体中,也是使用点符号方法访问属性。这两个方法看上去很相似,但它们有两点大不同:

其一,我们不能发送消息给C 结构体,因为C 结构体根本没有可执行的方法。

其二,C 结构体绝不分配在heap 中,因此不能通过指针来访问到它。(注,它分配在stack 中。内存管理中分为heapstack

 

2 strong    weak

在定义@property 时,会有选项如strongweak 等。

strong 表示保存这个对象在heap 中直到不再有任何指针指向它。(注,我理解为所有指向它的指针不先设置为nil ,它就不会从heap 中清理。)

weak 表示保存这个对象在heap 中,只要其他人strongly 指向了它。如果它从heap 中清理了,会将所有指向它的指针调整为指向nil 。这个功能从iOS5 开始使用。(注,我理解为如果它从heap 中清理后,所有指向它的指针都会自动调整为nil 。)

但是这种清理heap 的机制不是垃圾回收机制,在iOS 上没有这种内存自动回收机制。它采用的一种更好的机制,称之为引用计算(reference counting )。这种机制可以展开来讲很多,但在iOS 中又有了新机制,称为自动应用计算(ARC) 。了解它可以有助于理解内存管理。

iOS 中还有一种内存释放方法,为dealloc

- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

这种方法很少会用到,因为如果用到它,则太迟了。估计iOS 已经将应用给杀死了。

 

3 nil

这是一个对象指针的值,表示不指向任何对象。它和原始类型如int double 的“zero “很相似。

在实例变量中,作为一个对象指针类型定义的,其初始值都是nil 。如

id obj = nil;
NSString *hello = nil;

 nil 还有一个隐藏的功能,就是它可以放在if 语句中做条件判断。

if (obj) {run something;} 这个语句,objnil 时则不执行,不为nil 则执行。

对于指针值为nil 的实例变量,任何调用该对象中方法,都不会出错,没有任何方法会被执行。这可以理解为向nil 发送消息时,没得执行啊。

该操作的返回值是0 。如果int i = [obj methodWhichReturnsAnInt]; 则没有问题,返回结果是0 ,属于int 类型;如果CGPoint p = [obj getLocation]; 则就有问题了,返回结果还是0 ,而0 不是CGPoint 类型。CGPoint 是一个C 结构体。(注,类型不一致,会不会crash?

 

4 BOOL 类型

Objective-C ,也有一种布尔类型,实质上它是typedef

它可以用来做条件判断

if (flag) { }

if (!flag) { }

YES 值意思为trueNO 值意思为false

N0 值等于0YES 值除0 之外所有的数字

 

 

5 、实例方法和类方法

这个知识点很重要,在obj-c 中使用范围很广。他们之间区别有下列几点需要说明。

第一,命名方式上的差别,实例方法是以“- ”开始,类方法是以“+ ”开始。

- (BOOL)dropBomb:(Bomb *)bomb at:(CGPoint)position from:(double)altitude;// 这是实例方法在.h 文件中的声明

+ (id) alloc;// 这是类方法

+ (Ship *)motherShip;

+ (NSString *)stringWithFormat:...

 

第二,调用语法的差别。

实例方法只能实例去调用,语法为[<pointer to instance> method]

例子:

Ship *ship = ...; // instance of a Ship

destroyed = [ship dropBomb:firecracker at:dropPoint from:300.0];

同样,类方法只能用类去调用,语法为[Class method]

例子:

Ship *ship = [Ship motherShip];//Ship 是一个类

NSString *resultString =[NSString stringWithFormat:@“%g”, result];//NSString 也是一个类型

[[ship class] doSomething];//ship 是一个实例化的对象,必须使用[ship class] 转换成类后才能调用类方法,而直接使用ship 实例无法调用到类方法。

(注,首字符为大写的都是类,小写的则是实例化的对象,这是命名规则)

 

第三,self/super 的区别

在类中,使用self/super 的结果都是类;

在实例中,使用self/super 的结果都是实例;

 

 

6 、实例化( Instantiation

其一,使用其他对象创建自己的对象,如

NSString’s - (NSString *)stringByAppendingString:(NSString *)otherString;

NSString’s & NSArray’s - (id)mutableCopy;

NSArray’s - (NSString *)componentsJoinedByString:(NSString *)separator;

其二,也不是所有的使用其他对象创建而生成的对象都是新建的,有的对象会只是一个指针,而不是在heap 中再划分内存创建对象。如,

NSArray’s - (id)lastObject;

NSArray’s - (id)objectAtIndex:(int)index;

但是,如果使用copy 关键字,则会创建新对象。

其三,还可以使用类方法创建对象,如

NSString’s + (id)stringWithFormat:(NSString *)format, ...

UIButton’s + (id)buttonWithType:(UIButtonType)buttonType;

NSMutableArray’s + (id)arrayWithCapacity:(int)count;

NSArray’s + (id)arrayWithObject:(id)anObject;

 

其四,使用Allocating    initializing 创建新对象

例如:

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

CalculatorBrain *brain = [[CalculatorBrain alloc] init];

Allocating 是通过NSObject 的类方法allocheap 中分配一个空间给新对象。如@synthesize 就是执行这个操作。因此所有的@sythesize 的对象都已经在heap 中分配了一个足够大的内存空间。但这只是第一步,如果要使用该对象,还必须初始化,否则会直接crash

Initializing 对于多数类而言,都有很多方法,但NSObject 类只有一个初始化方法为init

例如:

- (id)initWithFrame:(CGRect)aRect; // initializer for UIView

UIView *myView = [[UIView alloc] initWithFrame:thePerfectFrame];

 

- (id)initWithCharacters:(const unichar *)characters length:(int)length;

- (id)initWithFormat:(NSString *)format, ...;

- (id)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding;

 

在开发类时,初始化方法中的返回类型建议设置成id ,这样做是为了继承。如果它的子类使用它的初始化方法时,直接使用id 类型即可。

例如:

@implementation MyObject

- (id)init

{

self = [super init]; // call our super’s designated initializer

if (self) {

// initialize our subclass here

}

return self;

}

@end

 

7 、动态绑定

其一,所有的对象都被分配在heap 中,所以你一直可以使用指针

例如:

NSString *s = ...; //  静态类型定义

id obj = s; //  非静态类型定义,但完全合法,不要使用”id *” 因为它表示一个指针的指针。

 

其二,在runtime 时才会知道运行的代码是什么

静态类型如第一点所说的NSString *id 的比较,静态类型只不过在编译时更有利于我们发现bug

如果runtime 时,没有找到所运行的代码,就crash 。但我们可以使用“introspection ”去判断代码是否可以执行。

 

8 、自省( introspection

自省是对象的固有能力,即程序运行时,对象可根据请求对外透露自身基本特性。您可以给对象发送某种消息,向其询问与它自身相关的问题,对象在Objective-C  运行时将会向您提供答案。自省是很重要的编码工具,它可以让程序变得更加高效健壮。

所有的继承了NSObjec 的对象有拥有下列三个方法:“

isKindOfClass: returns whether an object is that kind of class (inheritance included)

isMemberOfClass: returns whether an object is that kind of class (no inheritance)

respondsToSelector: returns whether an object responds to a given method

方法1 的参数值为[NSString class] ,即发送一个名为class 的类方法给一个类而得到。例如:

if ([obj isKindOfClass:[NSString class]]) {

NSString *s = [(NSString *)obj stringByAppendingString:@”xyzzy”];

}

 

方法3 的参数值为一个选择器,如@selector(shoot)

如果对象中有这个方法shoot ,就响应为true 。例如:

if ([obj respondsToSelector:@selector(shoot)]) {

[obj shoot];

} else if ([obj respondsToSelector:@selector(shootAt:)]) {

[obj shootAt:target];

}

 

介绍一种新类型SEL ,它是Objective-C 用于选择器的类型。

SEL shootSelector = @selector(shoot);

SEL shootAtSelector = @selector(shootAt:);

SEL moveToSelector = @selector(moveTo:withPenColor:);

 

NSObject 类中,可以通过方法performSelector:  或者  performSelector:withObject: 来执行选择器。例如:

[obj performSelector:shootSelector];

[obj performSelector:shootAtSelector withObject:coordinate];

 

NSArray 类中,可以通过makeObjectsPerformSelector: 来执行选择器操作。例如:

[array makeObjectsPerformSelector:shootSelector]; // cool, huh?

[array makeObjectsPerformSelector:shootAtSelector withObject:target]; // target is an id

 

UIButton 类中,可以通过  - (void)addTarget:(id)anObject action:(SEL)action ...; 方法来执行选择器。例如:

[button addTarget:self action:@selector(digitPressed:) ...];

 

 

9 、基础框架

NSObject

IOS SDK 中,NSObject 是基础类,实现一些方法,如自省的方法等等。

- (NSString *)description is a useful method to override (it’s %@ in NSLog()).

- (id)copy; // not all objects implement mechanism (raises exception if not)

- (id)mutableCopy; // not all objects implement mechanism (raises exception if not)

 

还有这些常用架构,如NSStringNSMutableStringNSNumber (原始类型  int, float, double, BOOL 等等的封装成对象),NSValueNSDataNSDate

还有一些集合类型如NSArrayNSMutableArrayNSDictionaryNSMutableDictionaryNSSetNSMutableSetNSOrderedSetNSMutableOrderedSet 。这些分成三种类别,分别为array,dictionary,set

这些类可以使用for in  方法遍历访问他们的成员。

还有Property ListNSUserDefaults 两个,也需要关注一下。

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics