19

I'm unfamiliar with Objective C.

I'm using a private framework and need to be able to change one of the properties from within my Swift code.

The property is declared in Objective C this way:

@property (nonatomic, assign) BOOL *isSSNField;

in swift I am trying to change the value of the property this way:

myClass.isSSNField = true

I am getting this error

Cannot assign a value of type 'Bool' to a value of type 'UnsafeMutablePointer<ObjcBool>'

I'm not sure where to go from here, or why I'm getting this error at all

qwerty
  • 2,065
  • 2
  • 28
  • 39
YichenBman
  • 5,011
  • 8
  • 46
  • 65
  • 4
    Are you sure that the property should be a *pointer* to a BOOL? – Martin R May 19 '15 at 18:11
  • 6
    `BOOL *isSSNField` Are you sure? That is a very unusual way to declare a property in Objective-C. A `BOOL*` is a very rare bird. I think it's fair to say that, although I have _encountered_ `BOOL*` in practice (especially in certain enumeration methods), I have never seen or used a `BOOL*` _property_ in my life. – matt May 19 '15 at 18:11
  • yes thats definitely the property – YichenBman May 19 '15 at 18:15
  • `BOOL*` looks indeed like a bug and should read just `BOOL`. – fluidsonic May 19 '15 at 18:18
  • 1
    More information would be helpful. Do you want to assign a value to the *pointer* itself, or to the boolean value that it *points to*? In the first case, should the pointer be allocated or not? Who is responsible for releasing the memory? – Martin R May 19 '15 at 18:21
  • @fluidsonic it was definitely a bug. I updated as you suggested and the error disappeared – YichenBman May 19 '15 at 18:23
  • I think I have a better fix, try and inform us pls – qwerty Dec 07 '15 at 14:48

5 Answers5

22

Update for Swift 5.1

For pointer types Swift provides pointee property,

Documentation for v5.1 says it is used for accessing instance referenced by this pointer

You can easily set the pointee field

myClass.isSSNField.pointee = false

And this is same for all pointer types and conversions. If you want to check the value of an Objective C BOOL* You can easily

if myClass.isSSNField.pointee.boolValue
qwerty
  • 2,065
  • 2
  • 28
  • 39
  • 4
    In Swift 3, `.memory` is now `.pointee`, for the cases I've seen so far. – alex bird Oct 20 '16 at 11:22
  • 1
    FWIW, `NSAttributedString` has `enumerateAttribute`, which returns one of these for use like a `break` in a loop. Confusing. – Jonny May 23 '17 at 01:22
21

I've never seen anything like the situation you describe, and personally I'm tempted to say the situation doesn't exist; I have never seen a BOOL* property or ivar in Objective-C in my life (and I'm darned old, believe me). However, if you insist: I haven't tested this, but I think you could say something like this:

var ok = UnsafeMutablePointer<ObjCBool>.alloc(1)
ok[0] = false // or true
let val = ok
myClass.isSSNField = val

However, although I think that will compile, I'm rather unclear on what the implications of doing it would be. It could cause the universe to collapse to a black hole, so be careful.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 14
    Yeah, you're giving me the checkmark now, but when the universe collapses to a black hole, you'll be back. – matt May 19 '15 at 18:24
  • I think I found something better before universe collapses :) – qwerty Dec 07 '15 at 14:47
  • [SBJson](https://github.com/stig/json-framework/blob/master/src/main/objc/SBJson4Parser.h) uses it typedef void (^SBJson4ValueBlock)(id item, BOOL* stop); and in Swift it is converted to: public typealias SBJson4ValueBlock = (AnyObject!, UnsafeMutablePointer) -> Void – theguy Mar 30 '16 at 19:03
  • 2
    @theguy That is a `Bool*` _function parameter_. Those are actually quite common, especially in blocks (as here). But that isn't what I said, is it? I said a `Bool*` _property_. – matt Mar 30 '16 at 21:07
  • 2
    @matt A Bool pointer is for any string enumeration routines, both in Objective-C and modern Swift. For example [[NSString enumerateSubstringsInRange:options:usingBlock:](https://developer.apple.com/reference/foundation/nsstring/1416774-enumeratesubstringsinrange?language=objc)]. – Bruno Philipe Mar 10 '17 at 23:05
  • @BrunoPhilipe See my previous comment. `Bool*` is common as a function parameter. But not as a property. Gosh, you just made me say the same thing twice. I hate that. – matt Mar 11 '17 at 00:19
17

BOOL* in Objective-C is a pointer of Bool.
Use UnsafeMutablePointer in Swift.

var isSSNField: ObjCBool = true
myClass.isSSNField = &isSSNField

Then fix it.

Just like the isDirectory parameter in function:

func fileExists(atPath path: String, isDirectory:UnsafeMutablePointer<ObjCBool>?) -> Bool

You can use the code:

var isDirectory:ObjCBool = true
var isFileExists = FileManager.default.fileExists(atPath: <#YourPath#>, isDirectory: &isDirectory)
TanJunHao
  • 216
  • 2
  • 2
7

The safer way to handle this would be very similar to @TanJunHao 's answer:

var isSSNField = ObjCBool(true)
myClass.isSSNField = &isSSNField
FromTheStix
  • 429
  • 5
  • 10
0

Look like your Objective C property declaration is incorrect. Please update like below and try

@property (nonatomic, assign)BOOL isSSNField;
Vinu David Jose
  • 2,569
  • 1
  • 21
  • 38