zoukankan      html  css  js  c++  java
  • 苹果开发之COCOA编程(第三版)下半部分

    第十八章:Image和鼠标事件

    1.NSResponder
    NSView继承自NSResponder类。所有的事件处理方法都定义在NSResponder类中。NSResponder申明了如下方法:
    - (void)mouseDown:(NSEvent *)theEvent;
    - (void)rightMouseDown:(NSEvent *)theEvent;
    - (void)otherMouseDown:(NSEvent *)theEvent;

    - (void)mouseUp:(NSEvent *)theEvent;
    - (void)rightMouseUp:(NSEvent *)theEvent;
    - (void)otherMouseUp:(NSEvent *)theEvent;

    - (void)mouseDragged:(NSEvent *)theEvent;
    - (void)scrollWheel:(NSEvent *)theEvent;
    - (void)rightMouseDragged:(NSEvent *)theEvent;
    - (void)otherMouseDragged:(NSEvent *)theEvent;

    2.NSEvent:一个事件对象包含了所有激发该事件的相关信息。当处理一个鼠标事件时,你应该会对这个方法感兴趣:
    - (NSPoint)locationInWindow;//返回事件发生的位置
    - (unsigned int)modifierFlags;//返回的整型数告诉你,用户按住了键盘上哪一个修饰键。这让程序员获得如Control-click和Shift-click的组合点击事件:

    - (void)mouseDown:(NSEvent*)e
    {
        unsigned int flags;
        flags = [e modifierFlags];
        if (flags & NSControlKeyMask){
            ...handle control click...
        }
        if (flags & NSShiftKeyMask){
            ...handle shift click...
        }
    }

    下面是一些常量,一般对这些修饰标记取AND(&):
    NSShiftKeyMask、NSControlKeyMask、NSAlertnateKeyMask、NSCommandKeyMask

    - (NSTimeInterval)timestamp;//此方法返回一个按秒计量的时间值,指的是从机器启动开始,到该事件发送时的时间量。NSTimeInterval为double类型
    - (NSWindow*)window;//返回发送事件的窗口
    - (int)clickCount;//单击、双击还是3击
    - (float)pressure;//如果用户使用一个压力输入设备,返回压力值

    - (float)deltaX;
    - (float)deltaY;
    - (float)deltaZ;//这三个方法获得鼠标或滚轮的位置改变量

    3.获取鼠标事件——必须在.m文件中重载鼠标事件方法

    4.View的坐标系统
    如果有两个view,a和b,要将NSPoint p 从b的坐标系统转换到a的坐标系统,可以这样:
    NSPoint q = [a coverntPoint:p fromView:b];//如果b为空,将从窗口的坐标系统转换到a的坐标系统

    第十九章:键盘事件

    1.NSResponder
    - (BOOL)acceptsFirstResponder;//将被子类重载,假如需要处理键盘事件则返回YES
    - (BOOL)resignFirstResponder;//询问接收对象是否要放弃first-responder状态
    - (BOOL)becomeFirstResponder;//通知接收对象成为窗口的first-responder
    - (void)keyDown:(NSEvent *)theEvent;//通知接收对象,用户按住了某个键
    - (void)keyUp:(NSEvent*)theEvent;
    - (void)flagsChanged:(NSEvent*)theEvent;//通知接收对象用户按住或放开了一个修饰键(如Shift或Control)

    2.NSEvent——以下通常是用在获得键盘事件信息的方法:
    - (NSString *)characters;//返回事件生成的字符
    - (BOOL)isARepeat;//当用户按住某键产生重复的键盘事件时返回YES,对于新的键盘事件则返回NO
    - (unsigned short)keyCode;//返回事件对应的键盘某个键的编码
    - (unsigned int)modifierFlags;//返回一个整型位数来指示对应的修饰键的状况

    第二十章:绘制带属性的文本

    1.NSFont。NSFont类只有两种类型的方法:
    a.得到想要字体的类方法
    b.得到字体尺度的方法,如字符的高度
    常用方法:
    + (NSFont *)fontWithName:(NSString *)fontName size:(float)fontSize;//fontName是family-face名称。fontSize如果设为0.0,就使用默认的用户字体大小
    //下面这些方法返回相对应类型的用户默认字体。如果fontsize为0.0,就使用默认大小
    + (NSFont *)userFixedPitchFontOfSize:(float)fontSize;
    + (NSFont *)userFontOfSize:(float)fontSize;
    + (NSFont *)messageFontOfSize:(float)fontSize;
    + (NSFont *)toolTipsFontOfSize:(float)fontSize;
    + (NSFont *)titleBarFontOfSize:(float)fontSize;

    2.NSAttributedString
    有时候你希望字符串中的某些字符使用特定的属性来显示。例如,你要显示“Big Nerd Ranch”,并希望给0到2的字符加上下划线,0到7的字符为绿色,9到13的字符显示为下标
    Cocoa使用结构NSRange来处理区间。它包含两个整型类型成员—location和length
    为了创建特定区间为效果字符的字符串,可以使用Cocoa类NSAttributedString和NSMutableAttributedString:

    NSMutableAttributedString *s;
    s = [[NSMutableAttributedString alloc] initWithString:@"Big Nerd Ranch"];
    
    [s addAttribute:NSFontAttributeName value:[NSFont userFontOfSize:22 range:NSMakeRange(0,14)];
    
    [s addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:1] range:NSMakeRange(0,3)];
    
    [s addAttribute:NSForegroundColorAttributeName value:[NSColor greenColor] range:NSMakeRange(0,8)];
    
    [s addAttribute:NSSuperscriptAttributeName value:[NSNumber numberWithInt:-1] range:NSMakeRange(9,5)];
    
    //一旦有了一个属性字符串,就可以给它添加很多要素
    [s drawInRect:[self bounds]];
    //将它设置给文本框
    [textField setAttributedStringValue:s];
    //将它设置给按钮
    [button setAttributedTitle:s];

    NSAttributedString可以读写下面的文件格式:
    String:读取一个文本文件
    RTF:Rich Text格式是多样字体、多样颜色的文本标准。你可以通过NSData对象来读取或设置属性字符串的内容
    RTFD:带有附件的RTF,可以包含图片
    HTML:属性字符串可以进行基本的HTML布局,不过最好使用webview
    Word:属性字符串可以读写简单地.doc文件
    OpenOffice

    3.绘制字符串和属性字符串
    NSAttributedString:
    - (void)drawAtPoint:(NSPoint)aPoint;//绘制字符串,aPoint为字符串的左下角
    - (void)drawInRect:(NSRect)rect;//绘制字符串。所有的绘制动作都再rect内部,如果rect装不下,字符串会被裁剪
    - (NSSize)size;//返回将会绘制的大小

    NSString:
    - (void)drawAtPoint:(NSPoint)aPoint withAttributes:(NSDictionary *)attribs//绘制带有attribs属性的字符串
    - (void)drawInRect:(NSRect)aRect withAttributes:(NSDictionary *)attribs;
    - (NSSize)sizeWithAttributes:(NSDictionary *)attribs;//返回使用属性attribs绘制时所需大小

    4.让你的View生成PDF数据
    所有的绘制命令都可以通过AppKit框架转换到PDF中。PDF数据可以发生给文件或打印机

    你创建一个view,view知道怎么生成pdf数据来描述自己的内容:
    - (NSData *)dataWithPDFInisdeRect:(NSRect)aRect;//这个方法会先创建一个数据对象,然后调用drawRect方法。这时这些绘制命令都会绘制到数据对象中,而不再是通常的屏幕。有了数据对象,只需要简单地将它保存到一个文件中

    5.NSFontManager:可以显示字体为粗体、斜体或压缩等等

    第二十一章:粘贴板和Nil-Targeted Actions

    1.粘贴板服务(pasteboard server)(usr/bin/pboard)是Mac系统上运行的一个进程。应用程序使用NSPasteboard类写入数据到该进程,或者从该进程读取数据。粘贴板服务让不同应用程序之间的复制、剪切、粘贴成为可能

    NSPasteboard类作为粘贴板服务的接口,下面是它常用的方法:
    + (NSPasteboard *)generalPasteboard;//返回常规的NSPasteboard,你将使用这个粘贴板复制、剪切和粘贴
    + (NSPasteboard *)pasteboardWithName:(NSString*)name;//根据名称返回某个粘贴板
    - (int)declareTypes:(NSArray *)types owner:(id)theOwner;//清空粘贴板中得数据,并声明调theOwner复制到粘贴板中得数据的类型
    //写输入到粘贴板
    - (BOOL)setData:(NSData *)aData forType:(NSString *)dataType;
    - (BOOL)setString:(NSString *)s forType:(NSString *)dataType;

    - (NSArray *)types;//返回一个数组,包含可以从粘贴板中读取的数据类型
    - (NSString *)availableTypeFromArray:(NSArray *)types;//返回粘贴板所能提供的所有数据类型中得第一个
    //从粘贴板读取数据
    - (NSData *)dataForType:(NSString *)dataType;
    - (NSString *)stringForType:(NSString *)dataType;

    2.Nil-Targeted Actions
    在众多视图中,如何正确地发送cut:、copy:或者paste:消息?——nil-targeted actions
    如果一个控件的target为空,应用程序则尝试发送action消息给多个对象,直到它们中的一个有响应。应用程序首先尝试给key window的first responder发送消息

    NSView、NSApplication和NSWindow都是继承自NSResponder,它们都有一个实例变量叫nextResponder。如果一个对象不响应nil-targeted acion,它的nextResponder就得到一个机会。
    视图的nextResponder通常是它的父视图。window的content view 的nextResponder就是window。因此把responder链接在一起就是响应链(向上回溯)

    如何搜索响应链
    1)keyWindow的firstResponder以及它的响应链。响应链一般包括父视图以及最终的key window
    2)key window的委托
    3)如果它是一个文档应用,还包括NSWindowController和key window的NSDocument对象
    4)如果main window和key window不同,它还有例行对main window依次检查一遍:
      a.main window的firstResponder以及它的响应链,包括main window自己
      b.main window的委托
      c.NSWindowController和main window的NSDocument对象
    5)NSApplication的实例
    6)NSApplication的委托
    7)NSDocumentController

    响应链就是这一系列的对象。对象依次被询问能否响应nil-targeted action
    我们知道给nil发送一个消息是不会发生任何事情的。事实上,所有的target/action消息都由NSApplication处理,它又下面这个方法:
    - (BOOL)sendAction:(SEL)anAction to:(id)aTarget from:(id)sender;
    当target为空时,NSApplication就知道要尝试给响应链上的对象发送消息了

    第二十二章:Categories

    1.给NSString添加一个方法

    #import <Foundation/Foundation.h>
    @interface NSString (FirstLetter)
    - (NSString*)BNR_firstLetter;
    @end
    ------------------------
    #import "FirstLetter.h"
    @implementation NSString (FirstLetter)
    - (NSString *)BNR_firstLetter
    {
        if ([self length] < 2){
            return self;  
        }
        NSRange r;
        r.location = 0;
        r.length = 1;
        return [self substringWithRange:r];
    }
    @end

    2.声明私有方法

    3.Protocol的非正式写法

    第二十三章:拖放

    第二十四章:NSTimer

    1.NSButton的实例有一个target和一个action(selector)。当按钮按下时,就发送action消息给target。
    Timer以相同的方式工作。Timer对象有一个target、一个selector、一个以秒为单位的延时。延时结束后,target会收到selector消息。Timer自己就是消息的参数

    2.NSRunLoop
    NSRunLoop对象专司等待。它等待事件抵达,然后把事件中转给NSApplication;它等待timer事件,然后把事件中转给NSTimer。你甚至可以附加一个网络socket到循环中,然后它就会等待那个socket上数据的抵达

    第二十五章:工作表

    1.一个工作表就是一个NSWindow实例,它附属于另外一个窗口。工作表覆盖在窗口上,窗口停止接受事件,直到工作表消失。
    NSApplication有下面几个方法来处理工作表:
    //启用一个工作表
    - (void)beginSheet:(NSWindow *)sheet modalForWindow:(NSWindow *)docWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contentInfo:(void*)contextInfo
    //结束一个工作表
    - (void)endSheet:(NSWindow*)sheet returnCode:(int)returnCode;

    2.窗口模式
    激活一个工作表后,用户就不能发送事件到宿主窗口。当警告面板(Alert Panel)运行时,它就是模式窗口——即阻止用户给任意其他窗口发送事件:
    - (int)runModalForWindow:(NSWindow *)aWindow;//只有发送给aWindow的的事件才会通过这个方法。而要让aWindow成为非模式窗口,可给NSApplication对象发送这个消息:
    - (void)stopModalWithCode:(int)returnCode;

    第二十六章:创建NSFormatter

    1.格式化器 接受一个字符串的输入,生成另外一个对象。如当输入字符串“3/17/1975”,NSDataFormatter就把它转换为一个1975年3月17日的NSData对象

    一个格式化器也可以接受一个对象的输入,然后生成一个用于显示的字符串。例如,文本框有一个NSDataFormatter,当文本框收到setObjectValue:的消息,消息参数是一个NSCalendarDate对象,date格式化器就会创建一个字符串代表那个日期,然后用户就看到那个字符串

    所有的格式化器都是NSFormatter的子类。Cocoa自带两个子类:NSDateFormatter和NSNumberFormatter
    大多数基础格式化器都要实现两个方法:
    //用户输入时,控制器(如文本框)要把一个字符串转换为一个对象,它给格式化器发送这个消息。格式化器可以返回YES并把anObject设置为指向新对象的指针。
    //如果返回NO,字符串不会被转换,同时设置errorPtr,指出差错所在,errorPtr是一个指向指针的指针。也就是说他是一个让你可以放置一个指向字符串的指针的地方
    - (BOOL)getObjectValue:(id*)anObject forString:(NSString *)aString errorDescription:(NSString *)errorPtr;

    2.NSControl的委托
    在格式化失败后,绑定机制会产生一个警告框。格式化失败也会通知文本框的委托。如果格式化器认为字符串是无效的,委托就会收到下面的报错信息:
    - (BOOL)control:(NSControl *)control didFailToFormatString:(NSString *)string errorDescription:(NSString *)error;

    3.让格式化器返回Attributed字符串——能让格式化器不仅能决定要显示什么字符串,还能决定如何显示它们:
    - (NSAttributedString *)attributedStringForObjectValue:(id)anObj withDefaultAttributes:(NSDictionary *)aDict;

    第二十七章:打印

    1.处理分页
    在你的视图中重载下面的两个方法:
    - (BOOL)knowsPageRange:(NSRange *)rptr;//有多少页
    - (NSRect)rectForPage:(int)pageNum;//每一个页的位置

    第二十八章:Web Service

    1.Web Service说到底不过是携带着XML数据的HTTP请求(request)和响应(response)而已
    HTTP的请求和响应由NSURL、NSURLRequest、NSURLConnection处理。生成以及解析XML一般由NSXMLDocument和NSXMLNode负责

    第二十九章:视图切换

    1.相比生成一个新窗口,更常见的情况是用一个视图替换另外一个视图。一个容易的实现方法就是改变box的content view

    第三十章:Core Data Relationships

    第三十一章:垃圾收集

    1.如果仅使用Object-c对象,垃圾收集器可以精准的完成它的工作。但是,只要开始 malloc C数据类型以及Core Foundation structures,就要小心了
    当垃圾收集器运行时,它会检索不可到达的对象。你可以把程序中的对象看成一个有向图:这个对象知道那个对象;它知道一些对象,然后这些对象又知道其他的对象,所以垃圾收集器从栈中的指针以及全局变量开始,遍历整个有向图,直到它记下所有的“可到达”对象。不可到达的对象被释放。

    2.非对象的数据类型

    a. C的原始类型
    如果有一个整数缓冲区,当它不可到达时你想让垃圾收集器释放它,这里有一个替代 malloc() 的方法:
    int *intBuff = NSAllocateCollectable(100*sizeof(int),0);

    当一个“知道”另外一个对象,我们说它有一个引用。引用可以是强或者是弱。垃圾收集器会注意强引用,但会忽略弱引用。因此如果我们只有一个弱引用指向intBuff,它将立即被垃圾收集器释放
    弱引用:有时我们需要一个对象指针,只要整个对象存在就一直指向它,但又不想因为这个指针的原因导致整个对象无法被垃圾收集器回传,这种情况使用弱引用
    尽管指针还指向这个对象,垃圾收集器还是会释放这个对象。如果指针指向一个已经被释放的对象,它会自动被设置为nil

    b.Core Foundation

    第三十二章:Core Animation

    1.CALayer——可被视为一个供绘制的缓冲区。layer也像视图那样以一定层次结构组织。视图被一个层(layer)覆盖,然后这个层还可以有子层
    一旦有了可以高速操纵的CALayer,我们就需要一些东西来驱动这个过程。而CAAnimation就是。NSAnimationContext用来群组以及同步多个animation

    常见子类:
    CATextLayer:可以更方便地在layer上绘制文本
    CAOpenGLLayer:可以更方便调用OpenGL

    视图的base layer是_NSViewBackingLayer的实例(不是一个公共类),知道如何绘制它上面的视图的内容

    第三十三章:一个简单地Cocoa/OpenGL应用程序

    1.NSOpenGLView是NSview的一个子类,有一个OpenGL的绘图上下文。NSOpenGLView的一些重要方法:
    - (id)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat *)format;//指定的初始化方法
    - (NSOpenGLContext *)openGLContext;//返回视图的OpenGL上下文
    - (void)reshape;//当视图调整大小时被调用。这个方法被调用时,OpenGL的上下文是活动的
    - (void)drawRect:(NSRect)r;//当视图需要重绘时调用它。这个方法被调用时,OpenGL的上下文是活动的

    第三十四章:NSTask

    1.你创建的每一个应用都是一个目录,目录里的某处有个可执行文件。要在一个Unix系统上(如Mac)运行可执行程序,首先会fork出一个进程,然后在新进程中执行文件中的代码。
    NSTask是一个为了便于使用Unix的fork()和exec()函数的包装器,通过指定一个可执行文件的路径并启动它。很多进程是从标准输入(standard-in)中读取数据并写回到标准输出(standard-out)和标准错误(standard-error)中,应用程序可以用NSTask附加管道(pipe)到外部进程上读取或发送数据,NSPipe类表示管道

    2.多线程对多进程

  • 相关阅读:
    redis-原理-数据结构-链表(二)
    redis-原理-数据结构-SDS(一)
    springMVC源码阅读-解决body不能重复读取问题(十二)
    spring-security使用-安全防护HttpFirewall(七)
    Redis-6.2.1 主从和哨兵模式配置
    Navicat 连接Mysql 8.0以上版本报错1251
    docker logs命令查看容器的日志
    Nginx 反向代理
    docker swarm 删除节点 (解散集群)
    Docker Swarm 命令学习
  • 原文地址:https://www.cnblogs.com/mumue/p/3303923.html
Copyright © 2011-2022 走看看