MVC:
Model:模型考虑的是什么,你的应用程序是什么(而不是你的程序是如何显示的),包括:数据,应用算法逻辑都是独立于UI存在于模型中的。
Controller:你的应用程序如何将Model显示给用户(UI逻辑)。
View:controller的随从(UI界面),Controller要使用的类
.h是公共API文件,存放你想要被访问的API,.m是其实现。
NSObject是IOS中所有类父类(包括我们自己做的类)。
所有的公共API都在:@interface和 @end之间,所有的API实现都在@implementation和@end之间.
然后要导入基础框架,通常我们在.h文件中直接导入经过预编译优化好的头文件:
例如,假设我们仅需要NSObject,我们可以#import<foundation>,但我们一般直接导入整个模块#import Foundation或者#import <foundation>,因为这是预编译及优化好的,所以速度很快,直接导入全部就可以了。/<foundation>/<foundation>
Object c会自动分配和释放内存,通过strong和weak,它们两分别代表指针属性,strong说明指针属性是强的,因为Object C要知道如何处理内存和堆
@property (strong) NSString *contents,只要在堆中有一个强指针指向它(这是引用计数不是垃圾回收),就不会被回收,只有不再存在任何强指针时,它才会从堆中立刻释放内存(不是之后的垃圾回收,时立刻释放)。
weak指针是弱引用,所引用的对象计数不会+1,只要还有strong指针指向它,就会将其留在内存中, 只要不再有强指针指向它,内存就会释放,此时这个weak指针会被设置为nil,在object c中可以发送消息给nil指针,它会返回0而程序不会崩溃。
指针回顾:
int a = 5; 系统编译时会对该变量分配地址,若a分配的地址是2000,则该语句的作用就是把常数5保存到地址为2000的单元。这种方式又称为直接访问,普通变量存放的是一个值,而指针变量是用来存放变量地址的,例如:
int *pointer;
pointer = &a;//a的地址2000存放到了pointer中了
如果要存取变量a的值,可先找到存放a的地址的变量pointer,取出a的地址(2000),然后取出a的值5。
*pointer表示该地址所对应的值。
*:取值操作符,int *pointer这里的*是声明该变量为指针变量的意思
&:取址操作符
知道了一个变量的地址,就可以通过这个地址来访问这个变量,因此又把变量的地址称为该变量的指针。
nonatomic:同该属性一同的setter和getter不是线程安全的,为什么不能是线程安全的呢?因为没必要,IOS的线程安全通常是在model与model,UI与UI之间的。
@property (strong, nonatomic) NSString *contents
我们不直接访问实例变量,通过声明@property IOS会帮我们自动生成get,set,我们可以指定get名称,但是get,set在实现文件中是看不到的,被隐藏了:
@synthesize content = _content;这行代码会创造一个带下划线前缀的实例变量名,同时使用这个属性生成getter和setter方法,这里的content需要跟.h文件中的@property对应上,其实就是给实例变量起个别名。
如果需要在set或get中做一些个性化的工作,那么可以使用@dynamic,这样getter和setter需要用户自己实现。
@property(nonatomic, getter=isChosen) BOOL chosen;
==用于比较指针,isEqualToString用于比较字符内容。
.操作符只能运用在setter和getter上。
在objective-C中所有的对象都存活在堆上。
[xxx alloc ] init 这是配套的使用的,init只能调用一次,千万别调用多次,alloc同样,不要多次在堆中分配。
定义单个参数的函数:
-(int) match:(NSArray *)otherCards;
定义多个参数的函数:
-(void) addCard:(Card *) card at_Top:(BOOL) atTop;
对应java的语法是:
public void addCard(Card card, bool atTop)
多参数的函数应该这么理解"addCard:at_Top:"是函数名,card和atTop是参数,所以at_Top实际上是方法名的一部分。
数组操作:cards是NSMutableArray类型,说实话语法有点不适应,但是不难看明白意思是在索引为0的位置插入card对象,第四行是说在末尾插入card对象。
if(atTop) {
[self.cards insertObject:card atIndex:0]
}else{
[self.cards addObject:card]
}
随机数操作:arc4random() % x:获取0到x-1之间的整数。
if([self.cards count]) {
unsigned index = arc4random() % [self.cards count];
randomCard = self.cards[index];
[self.cards removeObjectAtIndex:index];
}
创建数组,使用@[]语法来创建一个数组,举例如下:
-(NSString *) contents {
NSArray *rankStrings = @[@"?", @"A", @"2", @"3",@"4", @"5", @"6", @"7", @"8",
return [rankStrings[self.rank] stringByAppendingString:self.suit];
}
静态函数,方法前是+号为静态函数,-号为类函数,例如:
+(NSArray *) validSuits {
return @[@"♥️", @"♦️",@"♣️", @"♠️"];
}
init函数,在OC中,初始化立即发生在allocation之后,我们总是使用init来对类进行内存分配。例如:
Deck *myDeck = [[PlayingCardDeck alloc] init]
仅在调用alloc之后立即调用init方法,以在堆中为该新对象腾出空间。 并且只有在新分配给对象内存的时候调用alloc,其他情况禁止调用。instanceType是一个返回类型,它告诉编译器该方法返回一个对象,该对象的类型与此消息发送到的对象的类型相同。我们总是使用instanceType为init的返回对象。
-(instancetype) init {
self = [super init];
if(self) {
}
}
return self;
}
XCODE使用:
main.storyboard是我们的视图,双击可以打开手机视图主界面
Assets.xcassets:图片资源,1x是用于非视网膜屏;2x用于视网膜屏,原来的点坐标的大小乘2;3x:在原来的坐标上乘3
拖控件的地方在右上角,打开主视图(main.storyboard)后点击右上方的+号,中间面包就会出现空间面包,根据需要拖拉空间就可以了:
如下图所示先双击左边导航栏的Assets.xcassets,会出现右边的界面,可以把图片资源直接拖进来,也可以右键import,导入资源,可以直接在xcode中修改图片名字
设置图片的背景,例如拖拉一个空间后,选中这个空间,这个空间会浮现8个点方便你扩大,缩小,旋转灯操作,然后访问右边工具栏通过右上方的入口(有个向下的小箭头),选中它(下图右上方红色框框圈起来的),就会出现属性面板,根据个人需要自己配置即可。
特殊字符在edit - Emoji & Symbols,当然也可以通过快捷键访问:control +command+space
打开视图对照:
视图关联代码:选中按钮,按住control直接拖到代码中即可。
閱讀更多 北落師門Orz 的文章