发表于: 2017-01-12 00:17:36

2 872


今天完成的事情:刚完疯狂iOS讲义面向对象(上)并敲完书上的代码.

明天计划的事情:刚完面向对象(下)敲完所有代码;计划是月底看完上下册;

遇到的问题:有些知识点以前就知道,新的知识点现在这种难度的我也能看明白,所以没什么问题和不理解.

收获:

收获颇丰,这对我以后看别人的源码,还是框架必定有帮助.

如果堆内存里的对象没有任何变量指向该对象,那么程序将无法再访问该对象,Objective-C要求程序员释放该对象所占用的内存,否则就会造成内存泄露
self关键字总是指向调用该方法的对象.self关键字最大的作用就是让类中的一个方法访问该类的另一个方法或成员变量.
当局部变量和成员变量重名情况下,局部变量会隐藏成员变量.
@public 关键字用于暴露位于它下面的所有成员变量.
id类型可以代表所有对象的类型,任意类的对象都可以赋值给id类型的变量.
当通过id类型的变量来调用方法时,Objective-C将会执行动态绑定.所谓动态绑定,是指:Objective-C将会跟踪对象所属的类,它会在运行时判断该对象所属的类,并在运行时确定需要动态调用的方法,而不是在编译时确定要调用的方法.
va_list:这是一个类型,用于定义指向可变参数列表的指针变量.
va_start:这是一个函数,该函数指定开始处理可变形参的列表,并让指针变量指向可变形参列表的第一个参数.
va_end:结束处理可变形参,释放指针变量.
va_arg:该函数返回获取指针当前指向的参数的值,并将指针移动到指向下一个参数,
防止nil一定要严谨;
个数可变的形参只能处于形参列表的最后,一个方法只能有一个长度可变的形参.
OC的成员变量都是实例变量,并不支持真正的类变量.
import <Foundation/Foundation.h>
@interface FKPersion : NSObject
{
   
@public
   
NSString* _name;
   
int _age;
}
@end

@implementation FKPersion
@end

int main(int argc,const char* argv[])
{
   
FKPersion* p = [[FKPersion alloc] init];
   
NSLog (@"p变量的_name实例变量的值是: %@,p对象的_age成员变量的值是:%d",p->_name,p->_age);
    p->
_name = @"孙悟空";
    p->
_age = 500;
   
NSLog(@"p变量的_name实例变量的值是:%@,p对象的_age成员变量的值是:%d",p->_name,p->_age);
}

只要为一个类定义了实例变量,系统会为实例变量执行默认初始化,基本类型的实例变量默认被初始化为0,指针类型的成员变量默认被初始化为nil;
static关键字不能用于修饰成员变量,它只能修饰局部变量,全局变量和函数,static修饰局部变量表示将该局部变量储存到静态存储区;static修饰全局变量用于限制该全局变量只能在当前源文件中访问;static修饰函数用于限制该函数只能在当前源文件中调用;
如果一个类始终只能创建一个实例,则这个类被称为单利类.
单例类可通过static全局变量来实现,定义一个static全局变量,该变量用于保存已创建的singleton对象--------每次程序需要获取该实例时,程序先判断该static全局变量是否为nil,如果该全部变量为nil.则初始化一个实例并赋值给static全局变量.
隐藏和封装
将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问.
良好的封装可以实现以下目的:
1.隐藏类的实现细节.
2.让使用者只能通过实现预定的方法来访问数据,从而可以在该方法里加入控制逻辑.
3.可进行数据检查,从而有利于保证对象信息的完整性.
4.便于修改,提高代码的可维护性.
5.将对象的成员变量和实现细节隐藏起来,不允许外部直接访问.
6.把方法暴露出来,让方法来控制对这些成员变量进行安全的访问操作.


最基本的KVC由NSKeyValueCoding协议提供支持,最基本的操作属性的两个方法:
1.setValue:属性值 forKey:属性名:    为指定属性设置值
2.valueForKey:属性名:   获取指定属性的值.

#import <Foundation/Foundation.h>

@interface User : NSObject

@property (nonatomic,copy )NSString* name;
@property (nonatomic,copy) NSString* pass;
@property (nonatomic,copy) NSString* birth;


@end

@implementation User



@end

int main(int argc,const char* argv[])
{
   
User* u = [[User alloc] init];
    [u
setValue:@"孙悟空" forKey:@"name"];
    [u
setValue:@"1445" forKey:@"pass"];
    [u
setValue:[[NSDate alloc]init] forKey:@"birth"];
   
   
NSLog (@"username:%@", [u valueForKey:@"name"]);
   
NSLog (@"userpass:%@", [u valueForKey:@"pass"]);
   
NSLog (@"userbirth:%@", [u valueForKey:@"birth"] );
   
}


在KVC编程中,无论调用setValue:forKey方法,还是valueForKey:方法,都是通过NSString对象来指定被操作属性的.其中forKey:标签用于传入属性名.
对于setValue:属性值 forKey@“name”;代码,底层的执行机制如下:
(1).程序优先考虑调用”setName:属性值;”代码通过setter方法完成设置.
(2).如果该类没有setName方法,KVC机制会搜索该类名为_name的成员变量,无论该成员变量是在类接口部分定义,还是在类实现部分定义,也无论用哪个访问控制符修饰,这条KVC代码底层实际上就是对_name成员变量赋值.
(3)如果该类既没有setName:方法,也没有定义_name成员变量,KVC机制会搜索该类名为name的成员变量,无论成员变量实在类接口还是实现部分定义,也无论用哪个访问控制符修饰,这条KVC代码底层实际是对name成员变量赋值.
(4).如果上面三条都没有找到,系统将会执行该对象的setValue:forUndefinedKey;方法;
(默认的forUndefinedKey方法实现就是引发一个异常,这个异常将会导致因为异常结束.


对于”valueForKey@“name”;代码,底层的执行机制如下:
如上!
唯一不同程序有限考虑调用”name”代码来获取该getter方法的返回值.
#import <Foundation/Foundation.h>
@interface User : NSObject
{
   
@package
   
NSString* name;
   
NSString* _name;
}

@end

@implementation User

{
   
int age;
}


@end


int main (int argc,const char* argv[])
{
   
User* dog = [[User alloc] init];
    [dog
setValue:@"旺财" forKey:@"name"];
   
   
NSLog (@"dog->name: %@",dog->name);
   
NSLog (@"dog->_name: %@",dog->_name);
   
    [dog
setValue:[NSNumber numberWithInt:5] forKey:@"age"];
   
NSLog (@"dog age %@",[dog valueForKey:@"age"]);
   
}


努力奋斗!


返回列表 返回列表
评论

    分享到