【objective-c】初次学习objective-c问题汇总... 【暂完,待修改错误】

≡放荡痞女 提交于 2019-12-10 09:21:58

----------------------------------------------------------------------------------------

    这本书,我已经看过两遍,那两遍都是在买mac pro之前看的,目的是...因为语法怪怪的很有趣。
    好吧,也许还是有那么点歪心思的,现在买了电脑,第三遍看了,(⊙o⊙)…の,实践了才知道,中间会遇到这么多很纠结的问题。不过还好,速度比之前看要快很多很多了。。。

  是分割线

    终于全部实践了一次并写了一些小小的东西,不过还是不太熟练。接下来会继续看另外一本很基础的书,不过这本书就不会做笔记了,同时会跟着新买的一本口碑超赞的书进行实践练习,会有新笔记的。
    这篇笔记估计不会有太多的更新了,但如果在后面的学习和回顾中发现笔记里有错误的理解和看法,会进行修改与调整的。
    如果在看这篇笔记的你发现有什么问题,一定记得给我评论留言指出,O(∩_∩)O谢谢了!~

----------------------------------------------------------------------------------------

理解不透的问题:

1、内存管理:虽说可以自动管理内存,但是过来人说这个必须要懂,要非常懂。。。

2、类别和委托

3、NSCoding :对象的编码和解码

4、并发

5、NSPredicate

----------------------------------------------------------------------------------------

单独拎出来的概念:

开闭原则(Open / Closed Principle)

----------------------------------------------------------------------------------------

1、在xcode中无法在一个窗口打开多个项目,每个窗口只能存在一个项目。

  解决方案:cmd+~,就是tab上面一个键,可以在项目中快速切换。

2、conflicting types for ‘方法名’ 的错误。(Objective-C基础教程第三章中第一个实例练习时出错)

  解决方案:这里走的是C的语法,每个被调用的函数都需要在调用之前被声明。

3、Must explicitly describe intended ownership of an object array parameter(Objective-C基础教程第三章中最后一个实例练习时出错)


进行到第三章最后一个实例时,cmd+r运行会报错:Must explicitly describe intended ownership of an object array parameter。如果你看到了这个错误信息,你可以选中左边的项目名,然后再选中右边的PROJECT-->Apple LLVM compiler 4.2 - Language-->Objective-C Automatic Reference Counting,它本来的值是Yes,将它的值改为No(不自动管理内存),就可以正常编译运行了(如下截图所示)。


错误的大概意思是,必须为方法中数组参数分配明确地空间。

4、继承的工作机制:方法调度和实例变量

方法调度:发送消息时,首先在当前类中查找该方法,如果没有,则向该方法的superclass中进行查找。

实例变量:从上往下查找?实例变量不存在重新声明的情况吧?(⊙o⊙)…不太明。。(脆弱的基类问题?不懂。。mark)

5、linker command failed with exit code 1 (use -v to see invocation)(第六章切割文件时遇到)

参考:http://blog.csdn.net/duxinfeng2010/article/details/8265273

6、@class Tire;     // 使用方法和位置与 #import类似

@class 创建一个前向引用,并声明只会通过指针来引用该类。可以通过@class 让两个类互相引用。即,在A.h中用@class B,在B.h 中用@class A。但如果用 #import 让这两个类互相引用,就会出现编译错误。

7、在敲NSRange这章内容时,遇到一个纠结的问题,通过{5,5}或者NSMakeRange(5,5)给NSRange对象赋值会报错


其实是我自己犯傻,照着书copy,将NSRange重定义了,自然会出错了。

8、方法名前面的 + 与 -

最开始让我觉得无语的是,objective-c在方法前面加上的+和-,不过现在觉得挺好的,一目了然。

+:说明该方法是类方法,通常用于创建新的实例。例如,+ (id)stringWithFormat:(NSString *)format,...;

-:该方法为实例方法,我们直接在类中定义的起一定作用的方法。

9、NSArray的两个限制:只能存储objective-c对象,不能存储原始c数据类型;不能存储nil。

10、NSEnumerator 数组循环报错问题

NSArray *array = @[@"marong",@"hello"];
        NSEnumerator *enumerator = [array objectEnumerator];
        id thingie = [enumerator nextObject];
        while (thingie) {
            NSLog(@"I found %@", thingie);
            thingie = [enumerator nextObject];
        }
书中将 
id thingie = [enumerator nextObject];

while表达式中,报错,我将该句移到循环体外面,并在循环体内加上迭代语句,然后正常。

11、可变string、可变array和可变dictionary

12、NSNull,只有一个方法:+(NSNull *)null;

13、这么一个小程序也能让我觉得有趣啊

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        NSFileManager *manager;
        manager = [NSFileManager defaultManager];
        
        NSString *home;
        home = [@"~" stringByExpandingTildeInPath];
        
        NSDirectoryEnumerator *direnum;
        direnum = [manager enumeratorAtPath:home];
        
        NSMutableArray *files;
        files = [NSMutableArray arrayWithCapacity:42];
        
        NSString *filename;
        while (filename = [direnum nextObject]) {
            if ([[filename pathExtension] isEqualTo: @"jpg"]) {
                [files addObject:filename];
            }
        }
        
        NSEnumerator *fileenum;
        fileenum = [files objectEnumerator];
        
        while (filename = [fileenum nextObject]) {
            NSLog(@"%@",filename);
        }
        
    }
    return 0;
}
我发现我对所谓JS的各种特效越来越不耐烦,如果再没有一个统一的标准,日渐庞大而臃肿的JS队伍最终将溃不成军。一个写后台的同事问我,你为什么不写程序啊,我觉得你挺适合写程序的,你为什么选择切页面这种工作呢?是的,把时间都花在无谓的特效与动画上,而遗忘了自己的本质,不管是在别人眼中还是在你自己心里,永远都只是个切页面的。

无谓身边人如何唱衰IOS,不过我却觉得有意思起来。没有太多奇葩兼容的苦恼,虽然也要兼容低版本系统,可是相比web和android的兼容问题,那都是毛毛雨。系统现成的特效,可以把更多地精力花在业务逻辑和性能优化上,毕竟总得走的更远一点,只做一个程序员还是欠缺点什么。

14、关于快速枚举的一点不明:filewalkerV2实例中的片段

快速枚举使用的语法:
for ( Type newVariable in expression ) { statements }
for ( existingItem in expression ) { statements }
枚举期间对象不能被改变。
使用快速枚举的三个类:
NSArray, NSDictionary, NSSet

快速枚举的特性:可以将已有的NSEnumerator 对象或其子类传递给它。

NSFileManager *manager;
        manager = [NSFileManager defaultManager];
        
        NSString *home;
        home = [@"~" stringByExpandingTildeInPath];
        
        NSMutableArray *files;
        files = [NSMutableArray arrayWithCapacity:50];
        
        // [manager enumeratorAtPath:home] 的返回值类型为 NSDirectoryEnumerator
        for (NSString *filename in [manager enumeratorAtPath:home]) {
            if ([[filename pathExtension] isEqualTo: @"jpg"]){
                [files addObject:filename];
            }
        }
        
        for (NSString * filename in files) {
            NSLog(@"%@", filename);
        }

15、内存管理,很不明,mark

现在貌似用不到书上也就是后面截图那些了,自动生成的main函数中都会有下面这段代码:

@autoreleasepool {
    // do something here       
}



16、使用 NSString 的 convenience initializer 方法initWithContentsOfFile读取文件

int main(int argc, const char * argv[])
{    
    NSFileManager *manager;
    manager = [NSFileManager defaultManager];
    
    NSString *home;
    home = [@"~" stringByExpandingTildeInPath];
    
    NSLog(@"%@", home);
    NSString *path;
    path = [NSString stringWithFormat:@"%@/Documents/studyfile/资料网站搜集.txt", home];
    
    NSString *filestring;
    filestring = [[NSString alloc]
                  initWithContentsOfFile: path];
    
    NSLog(@"%@", filestring);
     
    return 0;
}

不知道有没有哪里写错了, ,等学的深一点了再回头来检查好了。反正log里面木有问题就是,哈哈。

17、指定初始化函数 designated initializer 的实际应用

#import <Foundation/Foundation.h>

@interface Tire : NSObject
{
    float pressure;
    float treadDepth;
}

- (id) initWithPressure: (float) pressure
              treadDepth: (float) treadDepth;

- (id) initWithPressure: (float) pressure;

- (id) initWithTreadDepth: (float) treadDepth;

@end

@implementation Tire
// 注意
- (id) init
{
    if (self = [self initWithPressure:34 treadDepth:20]){
    }
    
    return self;
}

- (id) initWithPressure:(float) p treadDepth:(float) t
{
    if (self = [super init]){
        pressure = p;
        treadDepth = t;
    }
    return (self);
}

- (id) initWithPressure:(float) p
{
    if (self = [self initWithPressure:p treadDepth:20]){
    }
    return (self);
}

- (id) initWithTreadDepth: (float) t
{
    if (self = [self initWithPressure:34 treadDepth:t]){
    }
    return (self);
}

- (NSString *) description
{
    NSString *desc;
    desc = [NSString stringWithFormat:@"Tire : Pressure : %.1f , TreadDepth : %.1f", pressure, treadDepth];
    return (desc);
}

@end

@interface TireSub : Tire
{
    float sub1;
    float sub2;
}

@end

@implementation TireSub
// 注意子类的 init 方法
- (id) init
{
    if (self = [super initWithPressure:34 treadDepth:20]){
        sub1 = 59;
        sub2 = 69;
    }
    return (self);
}

- (NSString *) description
{
    NSString *desc;
    desc = [NSString stringWithFormat:@"Tire : Pressure : %.1f , TreadDepth : %.1f, Sub1 : %.1f, Sub2 : %.1f", pressure, treadDepth,sub1,sub2];
    return (desc);
}
    
@end

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        TireSub *tiresub = [[TireSub alloc] init];
        NSLog(@"%@", tiresub);
        
    }
    return 0;
}

18、Property 实例

#import <Foundation/Foundation.h>

@interface MRProperty : NSObject
{
    NSString *name ;
    float address;
}

@property NSString *name;
@property float num;
@property(copy) NSString *string;              // for object type
@property(retain) NSMutableArray *array;       // for object type
@property NSString *secondName;
@property(readonly) NSString *lover;


- (id) initWithName: (NSString *) name
            address: (float) num;

@end

@implementation MRProperty  // !  Incomplete implementation

@synthesize name;
@synthesize num;

@synthesize string;
@synthesize array;

@synthesize secondName = second;
@synthesize lover;


- (id) init
{
    if ([self = self initWithName: @"ma" num: 40.0]) {
    }
    return (self);
}

- (id) initWithName: (NSString *) n num: (float) a
{
    if (self = [super init]) {
        name = [n copy];
        num = a;
        
        second = @"rong";
        lover = @"zsl";
    }
    return (self);
}

@end

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        MRProperty *property = [[MRProperty alloc] initWithName:@"ma" num:40];
        
        property.string = @"Hi, my love!~";
        
        NSLog(@"name is %@ ; num is %.1f ; string is %@.", property.name, property.num, property.string);
        NSLog(@"my second name is : %@", property.secondName);
        
        NSLog(@"my lover is : %@", property.lover);
    }
    return 0;
}

19、category   (类别)

感觉需要多用才能更明白一点。。。

20、protocol (协议)

我把它理解为 java里面的接口,在定义类时声明需要实现哪些接口。(⊙o⊙)…不知道对伐。哎呦,为啥我觉得java里面的接口更好理解呢?

protocol的声明示例如下:

@protocol Panel <NSObject>
// 必须实现
- (id) create;
// 可选
@optional
- (void) drawCicle;
- (void) drawDoted;
- (void) drawRect;
// 必须实现
@required
- (void) clearPanel;

@end

protocol的使用示例如下:

#import <Foundation/Foundation.h>
#import "Panel.h"

@interface Engine : NSObject <NSCopying,NSCoding>
@end

protocol的使用示例如下:

// 跟在id之后,要求对象遵守指定的协议
- (void) setObjectValue: (id<NSCopying>) obj;
// 用协议修饰方法的参数
- (void) draft: (Person<BaseballPlayer> *person);

21、block (块)

        int (^square_block)(int number) = ^(int number) {return (number * number);};
        int result = square_block(5);
        NSLog(@"%d",result);
        
        typedef double (^MKSampleMultiplyBlockRef)(double a, double b);  
        MKSampleMultiplyBlockRef multiply = ^(double a,double b){ return a * b;};
        MKSampleMultiplyBlockRef add = ^(double a,double b){ return a + b;};
        
        double a = 20, b = 40;
        __block double c = 3;
        MKSampleMultiplyBlockRef multiply2 = ^(double a, double b) {c = a * b;};
        // 如果不声明 __block ,则编译时会出错。
        // 没有长度的可变数组 和 没有长度的结构体 无法被声明为 __block 类型
        NSLog(@"%f",multiply(a,b));
        NSLog(@"%f",add(a,b));

block可以定义很多函数块,唯一的限制是这些函数块能拥有的参数只能是定义时的形参,不过它可以使用的变量的范围却很广。

全局变量、全局函数、封闭范围内的参数、函数级别的__block变量、封闭范围内的非静态变量会被获取为常量、objective-c的实例变量、代码块内部的本地变量

22、并发性

// 又是需要深究的一章

23、文件读取和写入

属性列表类,包括:NSArray、NSDirectory、NSString、NSNumber、NSDate、NSData

NSDate *date = [NSDate date];
        NSLog(@"today is %@", date);
        
        NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow: -(24 * 60 * 60)];
        NSLog(@"yesterday is %@", yesterday);
        
        const char *string = "hi, there, this is a c string!";
        NSData *data = [NSData dataWithBytes:string length: strlen(string) + 1];
        NSLog(@"data is %@", data);
        
        NSLog(@"%d byte string is '%s'", [data length], [data bytes]);
        
        NSArray *phrase;
        phrase = [NSArray arrayWithObjects:@"l", @"seem", @"to",@"be", @"very", @"sad" , nil];
        [phrase writeToFile:@"/Users/marong/Documents/test.txt" atomically:YES];
        // atomically 是否先写入缓冲区,(写入成功后再替换原文件,可避免写入失败损坏源文件,但须双倍磁盘空间)
        NSArray *phrase2;
        phrase2 = [NSArray arrayWithContentsOfFile:@"/Users/marong/Documents/test.txt"];
        NSLog(@"%@", phrase2);

// 2013-07-08 12:28:09.181 File[936:303] today is 2013-07-08 04:28:09 +0000
// 2013-07-08 12:28:09.181 File[936:303] yesterday is 2013-07-07 04:28:09 +0000
// 2013-07-08 12:28:09.182 File[936:303] data is <68692c20 74686572 652c2074 68697320 69732061 20632073 7472696e 672100>
// 2013-07-08 12:28:09.182 File[936:303] 31 byte string is 'hi, there, this is a c string!'
// 2013-07-08 12:28:09.183 File[936:303] (
    l,
    seem,
    to,
    be,
    very,
    sad
)

24、通过NSCoding协议编码和解码对象

// 表示又不太明白,脑子有点糊里糊涂的感觉了

25、提供逻辑上有意义的值,自定制空值:

-setNilValueForKey:

26、处理未定义的键(可重写默认方法)

-valueForUndefinedKey:

-setValue:forUndefinedKey;

27、简单键值操作示例

Car *car;
        car = [[Car alloc] initWithName:@"car1" modelYear:1988 numberOfDoors:1 mileage:1980.0];
        
        NSLog(@"%@", car);
        
        NSLog(@"%@", [car valueForKey:@"name"]);
        // valueForKey : 查找 -key 或 -isKey 命名的get方法,入不存在,则查找 对象内部名为 _key 或key 的实例变量。
        // c或c++中无法进行该操作
        
        [car setValue:@"Harold" forKey:@"name"];
        [car setValue: [NSNumber numberWithInt: 1988]
               forKey:@"modelYear"];
        
        NSLog(@"%@", car);
        
        [car setValue: [NSNumber numberWithFloat: 29.98]
               forKeyPath:@"engine.horsepower"];
        
        NSLog(@"%@", [car valueForKeyPath:@"engine.horsepower"]);
        NSLog(@"%@", [car valueForKeyPath:@"tires"]);
        // 如果路径中含有一个数组属性,则该键路径的其余部分将被发送给数组的每个对象
        
        NSNumber *num = [car valueForKeyPath:@"tires.@count"];
        NSLog(@"car has %d tires", num);
        // @count, @blah, @interface,@avg,@sum,@min,@max,@distinctUnionOfObjects (改变所有属性)

//Car-Value-Coding[2680:303] car1 , a 1988 1 1980.0 has 4 tires.
//Car-Value-Coding[2680:303] car1
//Car-Value-Coding[2680:303] Harold , a 1988 1 1980.0 has 4 tires.
//Car-Value-Coding[2680:303] 29.98
//Car-Value-Coding[2680:303] (
//    tires0,
//    tires1,
//    tires2,
//    tires3
//)
//Car-Value-Coding[2680:303] car has 1223 tires

28、NSPredicate:数组运算符 -- の,需要深入理解


29、NSPredicate:SELF

 NSArray *array = [NSArray arrayWithObjects:@"marong1", @"marong2", @"marong3", nil];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN {'Herbie', 'marong1', 'marong2'}"];
        
        NSArray *result;
        result = [array filteredArrayUsingPredicate:predicate];
        
        NSLog(@"%@", result);

//NSPredicate[3008:303] (
//    marong1,
//    marong2
//) 

31、@synchronized(object){ // critical section}  

// 确保不同线程会连续访问临界区的代码 (mark,关于并发性即多线程问题,不太明

当object为nil时,静态分析器将会发出警告。

@synchronize(mutex,atomic) // 系统自动生成,保证getter和setter方法互斥

31、新手注意事项大集合

    1》id类型:在Objective-C 中,id 类型是一个独特的数据类型。在概念上,类似Java 的Object 类,可以转换为任何数据类型。换句话说,id 类型的变量可以存放任何数据类型的对象。在内部处理上,这种类型被定义为指向对象的指针,实际上是一个指向这种对象的实例变量的指针。(参考:http://blog.csdn.net/lonelyroamer/article/details/7711895)

    2》在类的interface中,没有参数的方法后面不加冒号;

    3》[super 方法名: 参数];   // 在override superclass中的某个方法时,需要在方法最后面加上这句调用superclass中的该方法。

    4》self = [super init]    // 相关解释如下所示:

     5》继承&复合:inheritance & composition:is & has

     6》accessors :存取器

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!