我(正在尝试)学习Objective-C,我不断遇到如下的短语:
-(id) init;
Run Code Online (Sandbox Code Playgroud)
我理解的id是一个Objective C语言关键字,但是说"编译器id根据指针类型转换规则专门处理"是什么意思?
是否id自动将对象指定为其指针?
我在网上找到了一些信息来创建一个使用GCD的单例类.这很酷,因为它的线程安全,开销很低.遗憾的是,我找不到完整的解决方案,只能找到sharedInstance方法的片段.所以我使用试错法制作了自己的课 - 而且瞧瞧 - 以下内容出来了:
@implementation MySingleton
// MARK: -
// MARK: Singleton Pattern using GCD
+ (id)allocWithZone:(NSZone *)zone { return [[self sharedInstance] retain]; }
- (id)copyWithZone:(NSZone *)zone { return self; }
- (id)autorelease { return self; }
- (oneway void)release { /* Singletons can't be released */ }
- (void)dealloc { [super dealloc]; /* should never be called */ }
- (id)retain { return self; }
- (NSUInteger)retainCount { return NSUIntegerMax; /* That's soooo non-zero */ }
+ (MySingleton …Run Code Online (Sandbox Code Playgroud) 我做了一些快速搜索,无法找到答案.
我很想知道为什么在Objective-C中,它id被用作init方法的返回类型.
我的猜测是因为如果类被重写,你不想返回超类的类型的对象,但我有兴趣知道它是否由于其他原因而完成.
我被一种奇怪的行为所扰乱,如下例所示:
NSMutableArray *a1 = [[NSMutableArray alloc] init]; // fine
NSMutableArray *a2 = [NSMutableArray array]; // fine, too
// compiler reports incompatible pointer types; good:
NSMutableArray *a3 = [[NSArray alloc] init];
// compiler says nothing and is happy to assign this!
NSMutableArray *a4 = [NSArray array];
Run Code Online (Sandbox Code Playgroud)
这两个init和array的方法,无论是NSArray和NSMutableArray类返回id.但是,当我调用这些方法时的行为简直不一样,而clang让我愉快地NSArray为NSMutableArray变量分配一个空!
事实证明,clang会自动更改某些方法的返回类型,包括initfamily,toinstancetype,从而能够在编译时确定[[NSArray alloc] init]返回an NSArray *而不是an NSMutableArray *.但是这种检查根本不适用于该array方法.
为什么?不应该像我上一个例子那样的行至少 …
我试图在Obj-C中编写一个ActiveRecord-esque位代码,并遇到以下情况:我试图在基类中创建一个静态类变量,它获取继承类的名称并转换为表名使用复数和一些其他格式化操作.我知道对于一个类的实例,可以按照以下方式执行某些操作:
tableName = [[[self class] description] stringToTableName];
Run Code Online (Sandbox Code Playgroud)
但是,这需要使用一个self.可以沿着以下几行做点什么吗?
tableName = [[[inheriting_class class] description] stringToTableName];
Run Code Online (Sandbox Code Playgroud)
我只是不想为每个继承的类对象实例重新计算表名.我也更喜欢让这些代码用ruby风格的元编程自动生成表名.
看一下NSArray.h中的NSArray创建方法块.
返回id的方法是否有正当理由不返回instancetype?
Apple甚至努力添加内联注释,让我们知道id在这种情况下会返回一个NSArray.
@interface NSArray (NSArrayCreation)
+ (instancetype)array;
+ (instancetype)arrayWithObject:(id)anObject;
+ (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
+ (instancetype)arrayWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
+ (instancetype)arrayWithArray:(NSArray *)array;
- (instancetype)init; /* designated initializer */
- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt; /* designated initializer */
- (instancetype)initWithObjects:(id)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initWithArray:(NSArray *)array;
- (instancetype)initWithArray:(NSArray *)array copyItems:(BOOL)flag;
+ (id /* NSArray * */)arrayWithContentsOfFile:(NSString *)path;
+ (id /* NSArray * */)arrayWithContentsOfURL:(NSURL *)url;
- (id /* NSArray * */)initWithContentsOfFile:(NSString *)path;
- (id /* NSArray * */)initWithContentsOfURL:(NSURL *)url;
@end
Run Code Online (Sandbox Code Playgroud)
我能提出这些特殊方法的唯一方法就是Apple的这个指导 …
最近的Objective-C编译器引入了'instancetype'关键字,其中包括可用于提供类型集合的关键字...
我看到了instancetype的另一个目的,它在类的'objectWith'类型方法中使用它.例如:
@interface Car
+(instancetype)carWithWheels:(NSArray*)wheels;
@end
Run Code Online (Sandbox Code Playgroud)
理由是编译器将对initWith方法进行类型检查,但不对'objectWith'方法进行类型检查.
除了可能更容易键入外,使用'instancetype'代替实际的类名有什么好处?例如:
@interface Car
+(Car*)carWithWheels:(NSArray*)wheels;
@end
Run Code Online (Sandbox Code Playgroud) 我正在观看这个Swift教程并且有这一行:
var button:UIButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
Run Code Online (Sandbox Code Playgroud)
两个问题:
as UIButton?结尾?用户是否想要创建系统类型的按钮?这似乎是多余的.var button = UIButton.buttonWithType(UIButtonType.System)
我的意思是,如果等号后的部分正在初始化系统类型的按钮是不够的,编译器推断button是一个UIButton?我的意思是,Apple表示编译器很聪明地推断类型.
我观看了一些WWDC视频并注意到他们使用了其他东西而不是(id)返回未知对象的类型.
但遗憾的是我遗忘了关键字.
谁能告诉我为什么在返回一些对象时使用新东西而不是'id'?特别是在init和class方法中?
我一直在阅读和学习instancetype,在大多数情况下应该如何使用它而不是id现代的目标c.我可以问一下,什么时候才真正使用id而不是instancetype?谢谢.