MARK: - 了解Objective-C 语言起源
Objective-C 为C语言添加了 面向对象 的的特性
Objective-C是一门 动态绑定 的消息结构,也就是说运行时才会检查对象类型。接到消息之后,究竟应该执行何种代码,由运行期环境而非编译器来决定
//总结:
//1、对象所占用的内存 总是分配在 堆空间 中
//2、对象是分配在栈上的
//3、class 是引用类型、struct是值类型()
- (void)test01
{
// 1、someString变量 指向 NSString的指针,对象所占用的内存 总是分配在 堆空间 中
NSString *someString = @"the string";
// 2、anotherString变量 指向 同一块地址,并不拷贝改对象,只是这两个变量会同时指向此对象
NSString *anotherString = someString; //*** 浅拷贝 ***
NSLog(@"someString 内存地址:%p,someString = %@",someString,someString);
//0x10e1f2088 the string
NSLog(@"anotherString 内存地址:%p,anotherString = %@",anotherString,anotherString);
//0x10e1f2088 the string
// 3、
someString = @"the string is change";
NSLog(@"someString 内存地址:%p,someString = %@",someString,someString);
//0x10e1f20e8 the string is change //内存地址不一样,字面量重新创建一个字符串对象
NSLog(@"anotherString 内存地址:%p,anotherString = %@",anotherString,anotherString);
//0x10e1f2088 the string
//**************
MObject *m1 = [[MObject alloc] init];
m1.name = @"jack";
MObject *m2 = m1;
NSLog(@"m1 的内存地址:%@,m1 = %@",m1,m1.name); //0x6000000076f0 jack
NSLog(@"m2 的内存地址:%@,m2 = %@",m2,m2.name); //0x6000000076f0 jack
m2.name = @"rose";
NSLog(@"m1 的内存地址:%@,m1 = %@",m1,m1.name); //0x6000000076f0 rose
NSLog(@"m2 的内存地址:%@,m2 = %@",m2,m2.name); //0x6000000076f0 rose
}
MARK: - 了解Objective-C 命名规范
// 用系统方法举例子
- (void)example
{
// 驼峰命名法
// 以小写字母开头,其后每个单词首字母大写,而且前面通常还有两三那个前缀字母(自定义方法的生活,可以用于区别与系统的方法)
// 但方法名不能太长,必须言简意赅
NSString *text = @"this is text";
NSString *newText = [text stringByReplacingOccurrencesOfString:@"text"
withString:@"textString"];
NSLog(@"newText = %@",newText);
}
- (void)majqNamedForMethodTest
{
// 1、用于创建新的MPeson对象,方法名清晰的描述了返回值的类型
MPeson *p = [MPeson person];
// 获取p 的名字,这个方法只有一个词,实际上name 也是一个字符串属性
// 如果此方法命名StringName 就不好,string 一词多余
NSString *temVar = [p name];
NSLog(@"temVar = %@",temVar);
// 2、如果方法的返回值是新创建的,那么方法名的首个单词应该是返回值的类型,除非前面有修饰语,但是string 不能简写成str
[p stringBookNameByShoping];
// 3、应该把参数类型的名词放在参数前面
[p runWithFriend:nil name:@"jack"];
// 4、BOOl 属性应加is前缀,如果某方法返回非属性的Bool值,那么应该根据其功能,选用has或者is 当前缀
[p hasPet];
BOOL temVar01 = [p isMillionaire];
BOOL temVar02 = p.isMillionaire;
NSLog(@"temVar01 = %d temVar02 = %d",temVar01,temVar02);
NSString *text = @"http://www.baidu.com";
[text hasPrefix:@"http"];
[text isEqualToString:@"http://www.taobao.com"];
}
- (void)majqNamedForClasstest
{
// 1、应该为类与协议的名称加上前缀,以避免命名空间(nameSpace)冲突
// MPeson、NSArray、NSMutableArray
// 2、向 命名方法那么驼峰命名
// 3、*****命名方式应该协调一致*****
// 3.1 如果要从其他框架中继承子类,那么务必遵守其命名管理
// UIView --> MView
// 3.2 如果创建自定义的委托协议,则其名字中应该包含委托发起方的名称,后面再跟上 Delegate
}
MARK: - 在类的头文件中尽量少引用其他头文件
查看下面代码:
#import <Foundation/Foundation.h>
// 注意:***
#import "MajqNetworkFetcher.h"
// 注意:***
@interface MObject : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,strong)MajqNetworkFetcher *fetcher;
@end
// 注意:***
// MObject 添加属性fetcher时,常见的方法就是导入#import "MajqNetworkFetcher.h" 头问题
// 这种方法可行,但是不够优雅
// 因为编译的时候,MObject 不需要知道MajqNetworkFetcher类的全部细节,只需要知道有一个类名叫MajqNetworkFetcher 就好
// 所以,有个办法告诉编译器:@class MajqNetworkFetcher;
// 这叫 "向前声明"
#import <Foundation/Foundation.h>
// 注意:***
// MObject 添加属性fetcher时,常见的方法就是导入#import "MajqNetworkFetcher.h" 头问题
// 这种方法可行,但是不够优雅
// 因为编译的时候,MObject 不需要知道MajqNetworkFetcher类的全部细节,只需要知道有一个类名叫MajqNetworkFetcher 就好
// 所以,有个办法告诉编译器:@class MajqNetworkFetcher;
// 这叫 "向前声明"
#import "MajqNetworkFetcher.h"
@class MajqNetworkFetcher;
// 注意:***
@interface MObject : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,strong)MajqNetworkFetcher *fetcher;
@end
这样做的好处就是:
将头文件的时机尽量延后,只在确有需要的时候引入,这样做可以:
减少类的使用者所需引入的头文件数量,从而减少 编译时间
在实际开发过程中,我们可以这样去处理,但是,这样做也许会遇到一些问题:
比如说: @protocol
要声明你写的类遵守某个 协议@protocol,那么该协议必须要有完整的定义,且不能使用 向前声明 (向前声明@class 只能告诉编译器有某个协议,而此时编译器却要知道该协议中定义的方法)
那么怎么做呢??
通常做法是:
#import "MajqDataModel.h"
// 导入头文件
#import "MajqNetworkFetcher.h"
@interface MajqDataModel () <MajqNetworkFetcherDelegate>
@end
@implementation MajqDataModel
上面这种做法 没毛病,导入头文件 #import "MajqNetworkFetcher.h" 这个是在所难免的;
鉴于此,最好把协议 单独放在一个头文件中;
而要是把 MajqNetworkFetcherDelegate 放在 #import "MajqNetworkFetcher.h" 中,则只有引入头文件 #import "MajqNetworkFetcher.h" ,那么就会引入该头文件的所以内容
当然 这样做 有时候还是会有缺陷的,比如 委托协议,协议只有与接受协议委托的类放在一起定义才有意义
这个就不做具体的介绍,有时间在补充...