黑马程序员_第八天视频学习 类和对象的核心语法
2014-05-02 22:21
323 查看
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
一、 点语法
属于编译器特性
1、点语法与setter和getter有关
#import <Foundation/Foundation.h>
@interface Person :
NSObject
{
int _age;
NSString *_name;
}
- (void)setAge:(int)age;
- (int)age;
- (void)setName:(NSString *)name;
- (NSString *)name;
@end
@implementation Person
- (void)setAge:(int)age
{
_age = age;
NSLog(@"setAge");
// 会引发死循环
// self.age = age; // 相当于[selfsetAge:age];
}
- (int)age
{
NSLog(@"age");
// 访问的两种方法
return
_age;
// return self->_age;
// 会引发死循环
// return self.age; // 相当于[selfage];
}
- (void)setName:(NSString *)name
{
_name = name;
}
-(NSString *)name
{
return
@"Rose";
}
@end
int main(int argc,
const char * argv[])
{
Person *p = [Person
new];
[p setAge:10];
int a = [p
age];
NSLog(@"%d",a);
p.age =
15;
int b = p.age;
NSLog(@"%d",b);
p.name =
@"jack";
NSString *s = p.name;
NSLog(@"%@",s);
return
0;
}
p.age = 10;当编译器遇到点语法的时候,自动将代码转成[p setAge:10];
点语法的本质还是方法的调用;
点语法判定是set还是get方法,就是看是否赋值;
验证点语法的本质是setter\getter方法:在setter\getter里做打印或使用断点调试。
2、点语法的注意点
setter和getter里不能写self.age = age;或return self.age;会引发死循环。
二、 成员变量的作用域
有4种类型:
1)、@public:任何地方都能直接访问对象的成员变量
2)、@private:只能在当前类的对象方法中直接访问 (@implementation中默认就是@protected)
3)、@protected:可以在当前类和子类的对象方法中直接访问 (@interface中默认就是@protected)
4)、@package:只要处于同一个框架中,就能直接访问对象的成员变量,介于@private和@public之间的。
三、 @property和@synthesize
帮助类自动生成setter和getter,也属于编译器特性
1、 @property和@synthesize定义
@property 数据类型 成员变量名(去下划线 _ ):可以自动生成某个成员变量的setter和getter声明;@property用在@interface @end之间
@synthesize成员变量名(去下划线 _ ) = 成员变量名:可以自动生成某个成员变量的setter和getter实现,并且访问_age这个成员变量;@synthesize用在@implementation @end之间
2、定义成员变量的最简写法
@interface Car : NSObject
// 生成@private的数据类型为double的成员变量_height,并生成_height的setter和getter的声明和实现
@property double height;
@end
3、
若手动实现了setter,编译器只会自动生成getter和自动生成不存在的成员变量;
若手动实现了getter,编译器只会自动生成setter和自动生成不存在的成员变量;
若手动实现了setter和getter,编译器就不会自动生成不存在的成员变量;
四、 id
id(内部已包含*)是万能指针,能指向/操作任何OC对象(只适用于OC对象);
id 可以认为 id == NSObject *;
五、 构造方法
完整地创建一个可用的对象:
1)、分配存储空间(+alloc)
2)、初始化(+init)
创造对象不要用new,应使用
Person *p =[[Person alloc] init];
1、 构造方法:用来初始化对象的方法,是个对象方法,减号 – 开头;
2、 重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值。
重写 – init 方法
-(id)init
{
// 1、一定要调用回super的init方法:目的是初始化父类中声明的一些成员变量和其他属性
self = [super init]; // 当前对象 self
// 2、如果对象初始化成功,才有必要进行接下来的初始化
if (self != nil) {
// 初始化成功
_age = 10;
}
// 3、返回一个已经初始化完毕的对象
return self;
}
最终写法
- (id)init
{
if( self = [super init])
{
_age = 10;
}
return self;
}
3、 重写构造方法的注意点
a) 先调用父类的构造方法([super init])
b) 再进行子类内部成员变量的初始化
4、 自定义构造方法
自定义构造方法的规范
1)、一定是对象方法,一定以 - 开头
2)、返回值一般是id类型
3)、方法名一般以init开头
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property NSString *name;
@property int age;
- (id) initWithName:(NSString *)name;
- (id)initWithAge:(int)age;
- (id) initWithName:(NSString *)name andAge:(int)age;
@end
@implementation Person
- (id)initWithName:(NSString *)name
{
if ( self = [superinit] ) {
_name =name;
}
return self;
}
- (id)initWithAge:(int)age
{
if (self =[super init]) {
_age = age;
}
return self;
}
- (id)initWithName:(NSString *)name andAge:(int)age
{
if (self =[super init]) {
_age = age;
_name =name;
}
return self;
}
- (id)init
{
if (self =[super init]) {
_name =@"jack";
}
return self;
}
@end
@interface Student : Person
@property int no;
- (id)initWithNo:(int)no;
- (id) initWithName:(NSString *)name andAge:(int)ageandNo:(int)no;
@end
@implementation Student
- (id)initWithNo:(int)no
{
if (self =[super init]) {
_no = no;
}
return self;
}
/*
- (id)initWithName:(NSString *)name andAge:(int)ageandNo:(int)no
{
if ( self = [super init] )
{
_no = no;
self.name =name;
self.age =age;
// 第二种写法
// [selfsetName:name];
// [selfsetAge:age];
}
return self;
}
*/
// 父类的属性交给父类方法去处理,子类方法处理子类自己的属性
- (id)initWithName:(NSString *)name andAge:(int)ageandNo:(int)no
{
// 将父类定义的属性name、age传递到父类方法中进行初始化
if (self =[super initWithName:name andAge:age]) {
_no = no;
}
return self;
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool{
Person *p =[[Person alloc] init];
NSLog(@"%@",p.name);
Person *p1= [[Person alloc] initWithName:@"Rose"];
NSLog(@"%@",p1.name);
Person *p2= [[Person alloc] initWithAge:20];
NSLog(@"%d",p2.age);
Person *p3= [[Person alloc] initWithName:@"jim" andAge:19];
NSLog(@"name = %@, age = %d",p3.name,p3.age);
Student*stu = [[Student alloc] initWithNo:2];
NSLog(@"no = %d",stu.no);
Student*stus = [[Student alloc] initWithName:@"张三" andAge:16 andNo:5];
NSLog(@"name = %@, age = %d, no =%d",stus.name,stus.age,stus.no);
}
return 0;
}
六、 Category分类
可以给某一个类扩充一些方法(不修改原来的类的代码);
分类的作用:在不改变原来类模型(内容)的基础上,可以为类增加一些方法。
使用注意:
1)、分类只能增加方法,不能增加成员变量
2)、分类方法实现中可以访问原来类中的成员变量
3)、分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法没法再使用
4)、方法调用的优先级:分类(最后参与编译的分类优先) --> 原来类 --> 父类
/*
➢ 给NSString增加一个类方法:计算某个字符串中阿拉伯数字的个数
➢ 给NSString增加一个对象方法:计算当前字符串中阿拉伯数字的个数
*/
#import<Foundation/Foundation.h>
@interfaceNSString (Number)
-(int)numberCount;
+(int)numberCountOfString:(NSString *)str;
@end
@implementationNSString (Number)
//+(int)numberCountOfString:(NSString *)str
//{
// // 1、定义变量计算数字的个数
// int count = 0;
// for (int i = 0; i < str.length; i++) {
// // 2、取出i这个位置对应的字符
// unichar c = [str characterAtIndex:i];
//
// // 3、如果这个字符是阿拉伯数字,count自增1
// if ( c >= '0' && c <= '9') {
// count++;
// }
// }
// return count;
//}
+(int)numberCountOfString:(NSString *)str
{
return [str numberCount];
}
-(int)numberCount
{
int count = 0;
for (int i = 0; i < self.length; i++) {
unichar c = [self characterAtIndex:i];
if ( c >= '0' && c <= '9') {
count++;
}
}
return count;
}
@end
intmain(int argc, const char * argv[])
{
@autoreleasepool {
int count = [NSStringnumberCountOfString:@"sfa7sf6a78gsdfa7"];
NSLog(@"%d",count);
int counts = [@"hjsdhj4389jsdjk94"numberCount];
NSLog(@"%d",counts);
}
return 0;
}
七、 类的深入研究
1、类的本质
类也是一个对象,是Class类型的对象,简称类对象
// 利用Person这个类创建了Person类型的对象
Person *p = [[Person alloc] init];
Person *p1 = [[Person alloc] init];
// 获取内存中的类对象
Class c = [p class];
Class c1 = [p1 class];
Class c2 = [Person class];
NSLog(@"c = %p, c2 = %p, c2 =%p",c,c1,c2); // 输出结果都是一样的
本质是:
1)、利用Class 创建 Person类对象
2)、利用Person类对象 创建Person类型的对象
类名就代表类对象:类对象 == 类
2、+load方法和+initialize方法
1)、 当程序启动时,就会加载项目中所有的类和分类,而且加载完毕后就会调用每个类和分类的+load方法。只会调用一次;
2)、 当第一次使用某个类的时候,就会调用当前类和父类的+initialize方法,如果类有分类,按优先级加载+initialize方法;
3)、 先加载父类、再加载子类 (先调用父类的+load方法,再调用子类的+load方法),先初始化父类、再初始化子类 (先调用父类的+initialize方法,再调用子类的+initialize方法);
可以用+initialize监听类的初始化过程
八、 description
1、 -description方法
使用NSLog和%@输出某个对象时,会调用对象的-description方法,并拿到返回值进行输出
2、 + description方法
使用NSLog和%@输出某个类对象时,会调用类对象+description方法,并拿到返回值进行输出
3、 修改NSLog的默认输出
重写-description或者+description方法即可
@implementation Person
// 决定了实例对象的输出结果
- (NSString *)description
{
// 下面代码会引发死循环
//NSLog(@"%@",self);
return [NSString
stringWithFormat:@"name = %@, age =%d",_name,_age];
}
// 决定了类对象的输出结果
+ (NSString *)description
{
return
@"sdf";
}
@end
4、NSLog输出补充
//输出代码行号
NSLog(@"%d",__LINE__);
// NSLog输出C语言字符串的时候,不能有中文
// 输出源文件的名称
NSLog(@"%s",__FILE__);
printf("%s\n",__FILE__);
// 输出当前函数名
NSLog(@"%s",__func__);
九、 SEL
是一种类型,这种类型的数据就代表方法;
SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址,找到方法地址就可以调用方法;
每个类的方法列表都存储在类对象中;
每个方法都有一个与之对应的SEL类型的对象;
根据一个SEL对象就可以找到方法的地址,进而调用方法;
@interface Person :
NSObject
+ (void)test;
- (void)test2;
- (void)test3:(NSString *)abc;
@end
@implementation Person
+ (void)test
{
NSLog(@"+test");
}
- (void)test2
{
// _cmd代表着当前方法;每个方法内部都有一个内置的_cmd
NSString *str =
NSStringFromSelector(_cmd);
// 会引发死循环
// [selfperformSelector:_cmd];
NSLog(@"-test2 -- %@",str);
}
- (void)test3:(NSString *)abc
{
NSLog(@"test -- %@",abc);
}
@end
int main(int argc,
const char * argv[])
{
@autoreleasepool {
Person *p = [[Person
alloc] init];
// 间接调用test2方法
[p performSelector:@selector(test2)];
[p test3:@"ddff"];
[p performSelector:@selector(test3:)
withObject:@"vxwe"];
SEL s =@selector(test3:);
[p performSelector:s
withObject:@"sdf"];
[p test2];
// 1、首先会把test2包装成SEL类型的数据
// 2、根据SEL数据找到对应的方法地址
// 3、根据方法地址调用对应的方法
NSString *name =
@"test2";
SEL sl =
NSSelectorFromString(name);
[p performSelector:sl];
[p test2];
}
return
0;
}
其实消息就是SEL
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
一、 点语法
属于编译器特性
1、点语法与setter和getter有关
#import <Foundation/Foundation.h>
@interface Person :
NSObject
{
int _age;
NSString *_name;
}
- (void)setAge:(int)age;
- (int)age;
- (void)setName:(NSString *)name;
- (NSString *)name;
@end
@implementation Person
- (void)setAge:(int)age
{
_age = age;
NSLog(@"setAge");
// 会引发死循环
// self.age = age; // 相当于[selfsetAge:age];
}
- (int)age
{
NSLog(@"age");
// 访问的两种方法
return
_age;
// return self->_age;
// 会引发死循环
// return self.age; // 相当于[selfage];
}
- (void)setName:(NSString *)name
{
_name = name;
}
-(NSString *)name
{
return
@"Rose";
}
@end
int main(int argc,
const char * argv[])
{
Person *p = [Person
new];
[p setAge:10];
int a = [p
age];
NSLog(@"%d",a);
p.age =
15;
int b = p.age;
NSLog(@"%d",b);
p.name =
@"jack";
NSString *s = p.name;
NSLog(@"%@",s);
return
0;
}
p.age = 10;当编译器遇到点语法的时候,自动将代码转成[p setAge:10];
点语法的本质还是方法的调用;
点语法判定是set还是get方法,就是看是否赋值;
验证点语法的本质是setter\getter方法:在setter\getter里做打印或使用断点调试。
2、点语法的注意点
setter和getter里不能写self.age = age;或return self.age;会引发死循环。
二、 成员变量的作用域
有4种类型:
1)、@public:任何地方都能直接访问对象的成员变量
2)、@private:只能在当前类的对象方法中直接访问 (@implementation中默认就是@protected)
3)、@protected:可以在当前类和子类的对象方法中直接访问 (@interface中默认就是@protected)
4)、@package:只要处于同一个框架中,就能直接访问对象的成员变量,介于@private和@public之间的。
三、 @property和@synthesize
帮助类自动生成setter和getter,也属于编译器特性
1、 @property和@synthesize定义
@property 数据类型 成员变量名(去下划线 _ ):可以自动生成某个成员变量的setter和getter声明;@property用在@interface @end之间
@synthesize成员变量名(去下划线 _ ) = 成员变量名:可以自动生成某个成员变量的setter和getter实现,并且访问_age这个成员变量;@synthesize用在@implementation @end之间
2、定义成员变量的最简写法
@interface Car : NSObject
// 生成@private的数据类型为double的成员变量_height,并生成_height的setter和getter的声明和实现
@property double height;
@end
3、
若手动实现了setter,编译器只会自动生成getter和自动生成不存在的成员变量;
若手动实现了getter,编译器只会自动生成setter和自动生成不存在的成员变量;
若手动实现了setter和getter,编译器就不会自动生成不存在的成员变量;
四、 id
id(内部已包含*)是万能指针,能指向/操作任何OC对象(只适用于OC对象);
id 可以认为 id == NSObject *;
五、 构造方法
完整地创建一个可用的对象:
1)、分配存储空间(+alloc)
2)、初始化(+init)
创造对象不要用new,应使用
Person *p =[[Person alloc] init];
1、 构造方法:用来初始化对象的方法,是个对象方法,减号 – 开头;
2、 重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值。
重写 – init 方法
-(id)init
{
// 1、一定要调用回super的init方法:目的是初始化父类中声明的一些成员变量和其他属性
self = [super init]; // 当前对象 self
// 2、如果对象初始化成功,才有必要进行接下来的初始化
if (self != nil) {
// 初始化成功
_age = 10;
}
// 3、返回一个已经初始化完毕的对象
return self;
}
最终写法
- (id)init
{
if( self = [super init])
{
_age = 10;
}
return self;
}
3、 重写构造方法的注意点
a) 先调用父类的构造方法([super init])
b) 再进行子类内部成员变量的初始化
4、 自定义构造方法
自定义构造方法的规范
1)、一定是对象方法,一定以 - 开头
2)、返回值一般是id类型
3)、方法名一般以init开头
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property NSString *name;
@property int age;
- (id) initWithName:(NSString *)name;
- (id)initWithAge:(int)age;
- (id) initWithName:(NSString *)name andAge:(int)age;
@end
@implementation Person
- (id)initWithName:(NSString *)name
{
if ( self = [superinit] ) {
_name =name;
}
return self;
}
- (id)initWithAge:(int)age
{
if (self =[super init]) {
_age = age;
}
return self;
}
- (id)initWithName:(NSString *)name andAge:(int)age
{
if (self =[super init]) {
_age = age;
_name =name;
}
return self;
}
- (id)init
{
if (self =[super init]) {
_name =@"jack";
}
return self;
}
@end
@interface Student : Person
@property int no;
- (id)initWithNo:(int)no;
- (id) initWithName:(NSString *)name andAge:(int)ageandNo:(int)no;
@end
@implementation Student
- (id)initWithNo:(int)no
{
if (self =[super init]) {
_no = no;
}
return self;
}
/*
- (id)initWithName:(NSString *)name andAge:(int)ageandNo:(int)no
{
if ( self = [super init] )
{
_no = no;
self.name =name;
self.age =age;
// 第二种写法
// [selfsetName:name];
// [selfsetAge:age];
}
return self;
}
*/
// 父类的属性交给父类方法去处理,子类方法处理子类自己的属性
- (id)initWithName:(NSString *)name andAge:(int)ageandNo:(int)no
{
// 将父类定义的属性name、age传递到父类方法中进行初始化
if (self =[super initWithName:name andAge:age]) {
_no = no;
}
return self;
}
@end
int main(int argc, const char * argv[])
{
@autoreleasepool{
Person *p =[[Person alloc] init];
NSLog(@"%@",p.name);
Person *p1= [[Person alloc] initWithName:@"Rose"];
NSLog(@"%@",p1.name);
Person *p2= [[Person alloc] initWithAge:20];
NSLog(@"%d",p2.age);
Person *p3= [[Person alloc] initWithName:@"jim" andAge:19];
NSLog(@"name = %@, age = %d",p3.name,p3.age);
Student*stu = [[Student alloc] initWithNo:2];
NSLog(@"no = %d",stu.no);
Student*stus = [[Student alloc] initWithName:@"张三" andAge:16 andNo:5];
NSLog(@"name = %@, age = %d, no =%d",stus.name,stus.age,stus.no);
}
return 0;
}
六、 Category分类
可以给某一个类扩充一些方法(不修改原来的类的代码);
分类的作用:在不改变原来类模型(内容)的基础上,可以为类增加一些方法。
使用注意:
1)、分类只能增加方法,不能增加成员变量
2)、分类方法实现中可以访问原来类中的成员变量
3)、分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法没法再使用
4)、方法调用的优先级:分类(最后参与编译的分类优先) --> 原来类 --> 父类
/*
➢ 给NSString增加一个类方法:计算某个字符串中阿拉伯数字的个数
➢ 给NSString增加一个对象方法:计算当前字符串中阿拉伯数字的个数
*/
#import<Foundation/Foundation.h>
@interfaceNSString (Number)
-(int)numberCount;
+(int)numberCountOfString:(NSString *)str;
@end
@implementationNSString (Number)
//+(int)numberCountOfString:(NSString *)str
//{
// // 1、定义变量计算数字的个数
// int count = 0;
// for (int i = 0; i < str.length; i++) {
// // 2、取出i这个位置对应的字符
// unichar c = [str characterAtIndex:i];
//
// // 3、如果这个字符是阿拉伯数字,count自增1
// if ( c >= '0' && c <= '9') {
// count++;
// }
// }
// return count;
//}
+(int)numberCountOfString:(NSString *)str
{
return [str numberCount];
}
-(int)numberCount
{
int count = 0;
for (int i = 0; i < self.length; i++) {
unichar c = [self characterAtIndex:i];
if ( c >= '0' && c <= '9') {
count++;
}
}
return count;
}
@end
intmain(int argc, const char * argv[])
{
@autoreleasepool {
int count = [NSStringnumberCountOfString:@"sfa7sf6a78gsdfa7"];
NSLog(@"%d",count);
int counts = [@"hjsdhj4389jsdjk94"numberCount];
NSLog(@"%d",counts);
}
return 0;
}
七、 类的深入研究
1、类的本质
类也是一个对象,是Class类型的对象,简称类对象
// 利用Person这个类创建了Person类型的对象
Person *p = [[Person alloc] init];
Person *p1 = [[Person alloc] init];
// 获取内存中的类对象
Class c = [p class];
Class c1 = [p1 class];
Class c2 = [Person class];
NSLog(@"c = %p, c2 = %p, c2 =%p",c,c1,c2); // 输出结果都是一样的
本质是:
1)、利用Class 创建 Person类对象
2)、利用Person类对象 创建Person类型的对象
类名就代表类对象:类对象 == 类
2、+load方法和+initialize方法
1)、 当程序启动时,就会加载项目中所有的类和分类,而且加载完毕后就会调用每个类和分类的+load方法。只会调用一次;
2)、 当第一次使用某个类的时候,就会调用当前类和父类的+initialize方法,如果类有分类,按优先级加载+initialize方法;
3)、 先加载父类、再加载子类 (先调用父类的+load方法,再调用子类的+load方法),先初始化父类、再初始化子类 (先调用父类的+initialize方法,再调用子类的+initialize方法);
可以用+initialize监听类的初始化过程
八、 description
1、 -description方法
使用NSLog和%@输出某个对象时,会调用对象的-description方法,并拿到返回值进行输出
2、 + description方法
使用NSLog和%@输出某个类对象时,会调用类对象+description方法,并拿到返回值进行输出
3、 修改NSLog的默认输出
重写-description或者+description方法即可
@implementation Person
// 决定了实例对象的输出结果
- (NSString *)description
{
// 下面代码会引发死循环
//NSLog(@"%@",self);
return [NSString
stringWithFormat:@"name = %@, age =%d",_name,_age];
}
// 决定了类对象的输出结果
+ (NSString *)description
{
return
@"sdf";
}
@end
4、NSLog输出补充
//输出代码行号
NSLog(@"%d",__LINE__);
// NSLog输出C语言字符串的时候,不能有中文
// 输出源文件的名称
NSLog(@"%s",__FILE__);
printf("%s\n",__FILE__);
// 输出当前函数名
NSLog(@"%s",__func__);
九、 SEL
是一种类型,这种类型的数据就代表方法;
SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址,找到方法地址就可以调用方法;
每个类的方法列表都存储在类对象中;
每个方法都有一个与之对应的SEL类型的对象;
根据一个SEL对象就可以找到方法的地址,进而调用方法;
@interface Person :
NSObject
+ (void)test;
- (void)test2;
- (void)test3:(NSString *)abc;
@end
@implementation Person
+ (void)test
{
NSLog(@"+test");
}
- (void)test2
{
// _cmd代表着当前方法;每个方法内部都有一个内置的_cmd
NSString *str =
NSStringFromSelector(_cmd);
// 会引发死循环
// [selfperformSelector:_cmd];
NSLog(@"-test2 -- %@",str);
}
- (void)test3:(NSString *)abc
{
NSLog(@"test -- %@",abc);
}
@end
int main(int argc,
const char * argv[])
{
@autoreleasepool {
Person *p = [[Person
alloc] init];
// 间接调用test2方法
[p performSelector:@selector(test2)];
[p test3:@"ddff"];
[p performSelector:@selector(test3:)
withObject:@"vxwe"];
SEL s =@selector(test3:);
[p performSelector:s
withObject:@"sdf"];
[p test2];
// 1、首先会把test2包装成SEL类型的数据
// 2、根据SEL数据找到对应的方法地址
// 3、根据方法地址调用对应的方法
NSString *name =
@"test2";
SEL sl =
NSSelectorFromString(name);
[p performSelector:sl];
[p test2];
}
return
0;
}
其实消息就是SEL
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
相关文章推荐
- 黑马程序员_第六天视频学习 Objective-C的基本语法、类和对象
- 黑马程序员-我的第十篇学习日记:OC中点语法,@property和@synthesize,完整创建一个可用对象
- 黑马程序员——IOS基础---Objective-C第二段视频学习---面向对象---基本语法
- 黑马程序员学习笔记 JAVA高级视频_其他对象java.lang包中的类System与Runtime
- 黑马程序员_第一天视频学习 了解mac的基本使用和c语言基础语法
- 黑马程序员:OC学习日记之核心语法二
- “黑马程序员”视频学习笔记之面向对象基础及调试问题
- 黑马程序员_第七天视频学习 类和对象的三大特性
- 黑马程序员--IOS入学学习--8-OC核心语法
- CG学习(2)——CG的基本语法及核心函数的面向对象简单封装
- 黑马程序员—Objective-C学习—基本语法、类和对象
- 黑马程序员_第九天视频学习 类和对象的内存管理
- 黑马程序员——零基础学习iOS开发——10 Object-C 面向对象思想、OC语法简介、对象、类、
- 黑马程序员-iOS学习日记(七)面向对象-核心语法(二)
- 黑马程序员——03OCNSString类和核心语法学习
- 黑马程序员——IOS基础---Objective-C第一段视频学习---举例说明面向对象思想
- 【黑马程序员】Objective-C语言学习笔记之核心语法(四)
- 黑马程序员-iOS学习日记(六)面向对象-核心语法(一)
- 黑马程序员_毕向东_Java基础视频教程学习笔记(十八)
- C++开发者快速学习Objective-C语言核心语法