标签: objective-c-nullability

Objective-C中nullable,__nullable和_Nullable之间的区别

使用Xcode 6.3,引入了新的注释,以便更好地表达Objective-C中API的意图(并确保更好的Swift支持).那些注释当然是nonnull,nullablenull_unspecified.

但是使用Xcode 7,会出现很多警告,例如:

指针缺少可为空类型说明符(_Nonnull,_Nullable或_Null_unspecified).

除此之外,Apple使用另一种类型的可为空性说明符,标记其C代码(源代码):

CFArrayRef __nonnull CFArrayCreate(?CFAllocatorRef __nullable allocator, const void * __nonnull * __nullable values, CFIndex numValues, const CFArrayCallBacks * __nullable callBacks);

总而言之,我们现在拥有这3种不同的可空性注释:

  • nonnull,nullable,null_unspecified
  • _Nonnull,_Nullable,_Null_unspecified
  • __nonnull,__nullable,__null_unspecified

即使我知道为什么以及在哪里使用哪个注释,我也会对我应该使用哪种类型的注释,在哪里以及为什么感到困惑.这是我可以收集的:

  • 对于我应该使用性质nonnull,nullable,null_unspecified.
  • 对于我应该使用方法参数nonnull,nullable,null_unspecified.
  • 对于C方法我应该使用__nonnull,__nullable,__null_unspecified.
  • 对于其他情况,如双指针,我应该使用_Nonnull,_Nullable,_Null_unspecified. …

nullable objective-c objective-c-nullability

144
推荐指数
4
解决办法
4万
查看次数

指针缺少可空性类型说明符

在Xcode 7 GM中,我开始收到此警告:

指针缺少可为空类型说明符(_Nonnull,_Nullable或_Null_unspecified)

在以下函数声明中(NSUserDefaults扩展名)

- (void)setObject:(nullable id)value
           forKey:(NSString *)defaultName
    objectChanged:(void(^)(NSUserDefaults *userDefaults, id value))changeHandler
    objectRamains:(void(^)(NSUserDefaults *userDefaults, id value))remainHandler;
Run Code Online (Sandbox Code Playgroud)

为什么要显示此警告,我该如何解决?

objective-c ios objective-c-nullability

59
推荐指数
5
解决办法
4万
查看次数

Objective-C Nullability:符合条件的常量字符串

我已经养成了一个很好的习惯,即为NSNotification名字之类的东西声明和使用常量字符串.我声明他们是这样的:

extern NSString * const ABCAwesomeThingHappenedNotification;
Run Code Online (Sandbox Code Playgroud)

随着引进的Xcode 6.3和1.2雨燕的,我要回去,使用新雨燕与互操作和审计Objective-C类nonnull,nullablenull_unspecified预选赛.

将限定符添加到也具有外部可见静态字符串的标头时,我收到以下警告:

警告:指针缺少可为空类型说明符(__nonnull或__nullable)

嗯.那令人困惑/有趣.有人可以解释这条消息背后的原因吗?ABCAwesomeThingHappenedNotification在Swift中使用时,它从不暗示它是可选的String或隐式解包的String.

objective-c swift objective-c-nullability

23
推荐指数
2
解决办法
4010
查看次数

如何使编译器默认为"可空"

从Xcode 6.3开始,Objective-C中的类型可以标记为nullable或者nonnull,这是Apple的博客文章.

问题是,当两者都没有指定时,编译器会将Objective-C代码导入隐式解包到Swift中,例如NSView!.因此,当一个对象实际上 nil时,从Swift访问它时会崩溃.这并没有产生一个编译错误.

由于这非常容易失败,我希望编译器默认采用Objective-C中的所有内容nullable,除非另有指定nonnull,否则是审计区域宏NS_ASSUME_NONNULL_BEGIN / END.怎么能实现呢?

interop objective-c swift objective-c-nullability

14
推荐指数
1
解决办法
3343
查看次数

如何创建符合Swift和Objective-C之间共享协议的类方法?

我最近一直在学习Swift.

我决定编写一个混合的Swift/Objective-C应用程序,它使用两种语言实现的相同算法完成计算密集型任务.

该程序计算大量素数.

我定义了一个协议,Swift和Objective-C版本的计算对象都应该符合.

对象都是单例,所以我在Objective-C中创建了一个典型的单例访问方法:

+ (NSObject <CalcPrimesProtocol> *) sharedInstance;
Run Code Online (Sandbox Code Playgroud)

整个协议看起来像这样:

#import <Foundation/Foundation.h>
@class ComputeRecord;

typedef void (^updateDisplayBlock)(void);
typedef void (^calcPrimesCompletionBlock)(void);

    @protocol CalcPrimesProtocol <NSObject>

- (void) calcPrimesWithComputeRecord: (ComputeRecord *) aComputeRecord
              withUpdateDisplayBlock: (updateDisplayBlock) theUpdateDisplayBlock
                  andCompletionBlock: (calcPrimesCompletionBlock) theCalcPrimesCompletionBlock;

    @optional //Without this @optional line, the build fails.
    + (NSObject <CalcPrimesProtocol> *) sharedInstance;

    @end
Run Code Online (Sandbox Code Playgroud)

该类的Objective-C版本完全按照上面的定义实现方法,不用担心.

swift版本有一个方法:

  class func sharedInstance() -> CalcPrimesProtocol
Run Code Online (Sandbox Code Playgroud)

但是,如果我使该方法成为协议的必需方法,我得到编译器错误"类型"CalcPrimesSwift不符合协议'CalcPrimesProtocol'.

但是,如果我在协议中将单例类方法sharedInstance标记为可选,那么它可以工作,我可以在我的Swift类或Objective-C类上调用该方法.

我是否错过了Swift类方法定义中的一些细微之处?考虑到我可以在我的Swift类或Objective-C类上调用sharedInstance()类方法,这似乎不太可能.

您可以从Github下载该项目,如果您愿意,可以查看它.它叫做SwiftPerformanceBenchmark.(链接)

interop objective-c objective-c-protocol swift objective-c-nullability

9
推荐指数
1
解决办法
2319
查看次数

NSError,Swift和nullability

我在Objective-C中编写了一组工具,Swift将在某些时候使用这些工具,因此我使用了泛型和可空性.在这种情况下我该怎么办?

- (NSArray<MyObj *> * __nullable)foo:(NSError **)error;
Run Code Online (Sandbox Code Playgroud)

目前我收到警告:Pointer is missing a nullability type specifier...两个指针!我几乎可以肯定我不应该这样做:

- (NSArray<MyObj *> * __nullable)foo:(NSError * __autoreleasing __nullable * __nullable)error;
Run Code Online (Sandbox Code Playgroud)

我呢?

error-handling objective-c swift objective-c-nullability

7
推荐指数
1
解决办法
3348
查看次数

我们能否确保`+(nonnull instancetype)sharedInstance的可空性;`?

这是一个如何优雅地规避课堂上的可空性的init问题NSObject.

所以这是一个经典的objective-c实现:

+ (instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    static id sharedInstance;
    dispatch_once(&onceToken, ^
    {
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}
Run Code Online (Sandbox Code Playgroud)

但是现在我想声明它nonnull,如果可能的话:

+ (nonnull instancetype)sharedInstance;
Run Code Online (Sandbox Code Playgroud)

不幸的是,init返回一个nullable instancetype值.我应该NSAssert在打电话后添加一个什么东西init

我注意到有些人甚至将价值观记录nonnull在现实中nullable.那有意义吗?

我应该大胆地简单地添加到NS_ASSUME_NONNULL_BEGIN任何地方,而不是真正确保价值观nonnull吗?

nullable objective-c init non-nullable objective-c-nullability

6
推荐指数
1
解决办法
1623
查看次数

[UIView initWithFrame:]的文档冲突:是否可为空?

使用CLANG_ANALYZER_NONNULL(ie -Xclang nullability),我得到“ 从预期返回非空值的函数返回Null ”:

在此处输入图片说明

使用Xcode 7.3和iOS 9.3文档,我检查了一下initWithFrame:,它可以返回nil

描述

但是UIView.h用封装了所有内容NS_ASSUME_NONNULL_BEGIN,因此我们可以解释以下内容:

接口

如:

- (nonnull instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
Run Code Online (Sandbox Code Playgroud)

因此文档说明了nullable,而标头文件说明了nonnull。信任哪一个?

我应该写:

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (!self) {
        // workaround for clang analyzer
        return (void * _Nonnull)nil;
    }
    // Initialization code
    return self;
}
Run Code Online (Sandbox Code Playgroud)

要么:

- (nonnull instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    // Initialization code
    return self;
}
Run Code Online (Sandbox Code Playgroud)

更新

Xcode文档已更新,现在为: initWithFrame:文档

因此,不再有冲突。

objective-c uiview ios initwithframe objective-c-nullability

6
推荐指数
1
解决办法
347
查看次数

什么是警告的原因"指针缺少可空性类型说明符"?

+ (UIColor*) getColorWithHexa(NSString*)hexString;
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述:

这是我班上的方法定义.这引起了警告.什么是类似警告的原因以及如何解决这些问题?

我正在返回一个UIColor对象,而该问题与块有关,在注释中给出.

所以,它很有帮助.

ios objective-c-nullability

6
推荐指数
2
解决办法
4837
查看次数

如何在Objective-C中安全地将`_Nullable`强制转换为`_Nonnull`?

在编译时-Wnullable-to-nonnull-conversion,我们会使用以下代码获得正确的警告:

NSString * _Nullable maybeFoo = @"foo";
^(NSString * _Nonnull bar) {  
}(maybeFoo);

Tests.m:32:7: error: implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull' [-Werror,-Wnullable-to-nonnull-conversion]
    }(maybeFoo);
      ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

我如何安全地foo从一个演员阵容NSString * _Nullable到一个NSString * _Nonnull

到目前为止我有最好的解决方案

我想出的最好的就是这个宏:

#define ForceUnwrap(type, nullableExpression) ^type _Nonnull () { \
  type _Nullable maybeValue___ = nullableExpression; \
  if (maybeValue___) { \
    return (type _Nonnull) maybeValue___; \
  } else { \
    NSLog(@"Attempted to …
Run Code Online (Sandbox Code Playgroud)

xcode nullable objective-c ios objective-c-nullability

5
推荐指数
1
解决办法
3589
查看次数